]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/go/internal/load/pkg.go
[dev.boringcrypto] all: merge master (2f0da6d) into dev.boringcrypto
[gostls13.git] / src / cmd / go / internal / load / pkg.go
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         "context"
11         "encoding/json"
12         "errors"
13         "fmt"
14         "go/build"
15         "go/scanner"
16         "go/token"
17         "io/fs"
18         "os"
19         "path"
20         pathpkg "path"
21         "path/filepath"
22         "runtime"
23         "sort"
24         "strconv"
25         "strings"
26         "unicode"
27         "unicode/utf8"
28
29         "cmd/go/internal/base"
30         "cmd/go/internal/cfg"
31         "cmd/go/internal/fsys"
32         "cmd/go/internal/modinfo"
33         "cmd/go/internal/modload"
34         "cmd/go/internal/par"
35         "cmd/go/internal/search"
36         "cmd/go/internal/str"
37         "cmd/go/internal/trace"
38         "cmd/internal/sys"
39
40         "golang.org/x/mod/module"
41 )
42
43 var IgnoreImports bool // control whether we ignore imports in packages
44
45 // A Package describes a single package found in a directory.
46 type Package struct {
47         PackagePublic                 // visible in 'go list'
48         Internal      PackageInternal // for use inside go command only
49 }
50
51 type PackagePublic struct {
52         // Note: These fields are part of the go command's public API.
53         // See list.go. It is okay to add fields, but not to change or
54         // remove existing ones. Keep in sync with list.go
55         Dir           string                `json:",omitempty"` // directory containing package sources
56         ImportPath    string                `json:",omitempty"` // import path of package in dir
57         ImportComment string                `json:",omitempty"` // path in import comment on package statement
58         Name          string                `json:",omitempty"` // package name
59         Doc           string                `json:",omitempty"` // package documentation string
60         Target        string                `json:",omitempty"` // installed target for this package (may be executable)
61         Shlib         string                `json:",omitempty"` // the shared library that contains this package (only set when -linkshared)
62         Root          string                `json:",omitempty"` // Go root, Go path dir, or module root dir containing this package
63         ConflictDir   string                `json:",omitempty"` // Dir is hidden by this other directory
64         ForTest       string                `json:",omitempty"` // package is only for use in named test
65         Export        string                `json:",omitempty"` // file containing export data (set by go list -export)
66         BuildID       string                `json:",omitempty"` // build ID of the compiled package (set by go list -export)
67         Module        *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any
68         Match         []string              `json:",omitempty"` // command-line patterns matching this package
69         Goroot        bool                  `json:",omitempty"` // is this package found in the Go root?
70         Standard      bool                  `json:",omitempty"` // is this package part of the standard Go library?
71         DepOnly       bool                  `json:",omitempty"` // package is only as a dependency, not explicitly listed
72         BinaryOnly    bool                  `json:",omitempty"` // package cannot be recompiled
73         Incomplete    bool                  `json:",omitempty"` // was there an error loading this package or dependencies?
74
75         // Stale and StaleReason remain here *only* for the list command.
76         // They are only initialized in preparation for list execution.
77         // The regular build determines staleness on the fly during action execution.
78         Stale       bool   `json:",omitempty"` // would 'go install' do anything for this package?
79         StaleReason string `json:",omitempty"` // why is Stale true?
80
81         // Source files
82         // If you add to this list you MUST add to p.AllFiles (below) too.
83         // Otherwise file name security lists will not apply to any new additions.
84         GoFiles           []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
85         CgoFiles          []string `json:",omitempty"` // .go source files that import "C"
86         CompiledGoFiles   []string `json:",omitempty"` // .go output from running cgo on CgoFiles
87         IgnoredGoFiles    []string `json:",omitempty"` // .go source files ignored due to build constraints
88         IgnoredOtherFiles []string `json:",omitempty"` // non-.go source files ignored due to build constraints
89         CFiles            []string `json:",omitempty"` // .c source files
90         CXXFiles          []string `json:",omitempty"` // .cc, .cpp and .cxx source files
91         MFiles            []string `json:",omitempty"` // .m source files
92         HFiles            []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files
93         FFiles            []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files
94         SFiles            []string `json:",omitempty"` // .s source files
95         SwigFiles         []string `json:",omitempty"` // .swig files
96         SwigCXXFiles      []string `json:",omitempty"` // .swigcxx files
97         SysoFiles         []string `json:",omitempty"` // .syso system object files added to package
98
99         // Embedded files
100         EmbedPatterns []string `json:",omitempty"` // //go:embed patterns
101         EmbedFiles    []string `json:",omitempty"` // files matched by EmbedPatterns
102
103         // Cgo directives
104         CgoCFLAGS    []string `json:",omitempty"` // cgo: flags for C compiler
105         CgoCPPFLAGS  []string `json:",omitempty"` // cgo: flags for C preprocessor
106         CgoCXXFLAGS  []string `json:",omitempty"` // cgo: flags for C++ compiler
107         CgoFFLAGS    []string `json:",omitempty"` // cgo: flags for Fortran compiler
108         CgoLDFLAGS   []string `json:",omitempty"` // cgo: flags for linker
109         CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names
110
111         // Dependency information
112         Imports   []string          `json:",omitempty"` // import paths used by this package
113         ImportMap map[string]string `json:",omitempty"` // map from source import to ImportPath (identity entries omitted)
114         Deps      []string          `json:",omitempty"` // all (recursively) imported dependencies
115
116         // Error information
117         // Incomplete is above, packed into the other bools
118         Error      *PackageError   `json:",omitempty"` // error loading this package (not dependencies)
119         DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies
120
121         // Test information
122         // If you add to this list you MUST add to p.AllFiles (below) too.
123         // Otherwise file name security lists will not apply to any new additions.
124         TestGoFiles        []string `json:",omitempty"` // _test.go files in package
125         TestImports        []string `json:",omitempty"` // imports from TestGoFiles
126         TestEmbedPatterns  []string `json:",omitempty"` // //go:embed patterns
127         TestEmbedFiles     []string `json:",omitempty"` // files matched by TestEmbedPatterns
128         XTestGoFiles       []string `json:",omitempty"` // _test.go files outside package
129         XTestImports       []string `json:",omitempty"` // imports from XTestGoFiles
130         XTestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns
131         XTestEmbedFiles    []string `json:",omitempty"` // files matched by XTestEmbedPatterns
132 }
133
134 // AllFiles returns the names of all the files considered for the package.
135 // This is used for sanity and security checks, so we include all files,
136 // even IgnoredGoFiles, because some subcommands consider them.
137 // The go/build package filtered others out (like foo_wrongGOARCH.s)
138 // and that's OK.
139 func (p *Package) AllFiles() []string {
140         files := str.StringList(
141                 p.GoFiles,
142                 p.CgoFiles,
143                 // no p.CompiledGoFiles, because they are from GoFiles or generated by us
144                 p.IgnoredGoFiles,
145                 p.IgnoredOtherFiles,
146                 p.CFiles,
147                 p.CXXFiles,
148                 p.MFiles,
149                 p.HFiles,
150                 p.FFiles,
151                 p.SFiles,
152                 p.SwigFiles,
153                 p.SwigCXXFiles,
154                 p.SysoFiles,
155                 p.TestGoFiles,
156                 p.XTestGoFiles,
157         )
158
159         // EmbedFiles may overlap with the other files.
160         // Dedup, but delay building the map as long as possible.
161         // Only files in the current directory (no slash in name)
162         // need to be checked against the files variable above.
163         var have map[string]bool
164         for _, file := range p.EmbedFiles {
165                 if !strings.Contains(file, "/") {
166                         if have == nil {
167                                 have = make(map[string]bool)
168                                 for _, file := range files {
169                                         have[file] = true
170                                 }
171                         }
172                         if have[file] {
173                                 continue
174                         }
175                 }
176                 files = append(files, file)
177         }
178         return files
179 }
180
181 // Desc returns the package "description", for use in b.showOutput.
182 func (p *Package) Desc() string {
183         if p.ForTest != "" {
184                 return p.ImportPath + " [" + p.ForTest + ".test]"
185         }
186         return p.ImportPath
187 }
188
189 type PackageInternal struct {
190         // Unexported fields are not part of the public API.
191         Build             *build.Package
192         Imports           []*Package           // this package's direct imports
193         CompiledImports   []string             // additional Imports necessary when using CompiledGoFiles (all from standard library)
194         RawImports        []string             // this package's original imports as they appear in the text of the program
195         ForceLibrary      bool                 // this package is a library (even if named "main")
196         CmdlineFiles      bool                 // package built from files listed on command line
197         CmdlinePkg        bool                 // package listed on command line
198         CmdlinePkgLiteral bool                 // package listed as literal on command line (not via wildcard)
199         Local             bool                 // imported via local path (./ or ../)
200         LocalPrefix       string               // interpret ./ and ../ imports relative to this prefix
201         ExeName           string               // desired name for temporary executable
202         CoverMode         string               // preprocess Go source files with the coverage tool in this mode
203         CoverVars         map[string]*CoverVar // variables created by coverage analysis
204         OmitDebug         bool                 // tell linker not to write debug information
205         GobinSubdir       bool                 // install target would be subdir of GOBIN
206         BuildInfo         string               // add this info to package main
207         TestmainGo        *[]byte              // content for _testmain.go
208         Embed             map[string][]string  // //go:embed comment mapping
209
210         Asmflags   []string // -asmflags for this package
211         Gcflags    []string // -gcflags for this package
212         Ldflags    []string // -ldflags for this package
213         Gccgoflags []string // -gccgoflags for this package
214 }
215
216 // A NoGoError indicates that no Go files for the package were applicable to the
217 // build for that package.
218 //
219 // That may be because there were no files whatsoever, or because all files were
220 // excluded, or because all non-excluded files were test sources.
221 type NoGoError struct {
222         Package *Package
223 }
224
225 func (e *NoGoError) Error() string {
226         if len(e.Package.IgnoredGoFiles) > 0 {
227                 // Go files exist, but they were ignored due to build constraints.
228                 return "build constraints exclude all Go files in " + e.Package.Dir
229         }
230         if len(e.Package.TestGoFiles)+len(e.Package.XTestGoFiles) > 0 {
231                 // Test Go files exist, but we're not interested in them.
232                 // The double-negative is unfortunate but we want e.Package.Dir
233                 // to appear at the end of error message.
234                 return "no non-test Go files in " + e.Package.Dir
235         }
236         return "no Go files in " + e.Package.Dir
237 }
238
239 // setLoadPackageDataError presents an error found when loading package data
240 // as a *PackageError. It has special cases for some common errors to improve
241 // messages shown to users and reduce redundancy.
242 //
243 // setLoadPackageDataError returns true if it's safe to load information about
244 // imported packages, for example, if there was a parse error loading imports
245 // in one file, but other files are okay.
246 func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportStack, importPos []token.Position) {
247         matchErr, isMatchErr := err.(*search.MatchError)
248         if isMatchErr && matchErr.Match.Pattern() == path {
249                 if matchErr.Match.IsLiteral() {
250                         // The error has a pattern has a pattern similar to the import path.
251                         // It may be slightly different (./foo matching example.com/foo),
252                         // but close enough to seem redundant.
253                         // Unwrap the error so we don't show the pattern.
254                         err = matchErr.Err
255                 }
256         }
257
258         // Replace (possibly wrapped) *build.NoGoError with *load.NoGoError.
259         // The latter is more specific about the cause.
260         var nogoErr *build.NoGoError
261         if errors.As(err, &nogoErr) {
262                 if p.Dir == "" && nogoErr.Dir != "" {
263                         p.Dir = nogoErr.Dir
264                 }
265                 err = &NoGoError{Package: p}
266         }
267
268         // Take only the first error from a scanner.ErrorList. PackageError only
269         // has room for one position, so we report the first error with a position
270         // instead of all of the errors without a position.
271         var pos string
272         var isScanErr bool
273         if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 {
274                 isScanErr = true // For stack push/pop below.
275
276                 scanPos := scanErr[0].Pos
277                 scanPos.Filename = base.ShortPath(scanPos.Filename)
278                 pos = scanPos.String()
279                 err = errors.New(scanErr[0].Msg)
280         }
281
282         // Report the error on the importing package if the problem is with the import declaration
283         // for example, if the package doesn't exist or if the import path is malformed.
284         // On the other hand, don't include a position if the problem is with the imported package,
285         // for example there are no Go files (NoGoError), or there's a problem in the imported
286         // package's source files themselves (scanner errors).
287         //
288         // TODO(matloob): Perhaps make each of those the errors in the first group
289         // (including modload.ImportMissingError, ImportMissingSumError, and the
290         // corresponding "cannot find package %q in any of" GOPATH-mode error
291         // produced in build.(*Context).Import; modload.AmbiguousImportError,
292         // and modload.PackageNotInModuleError; and the malformed module path errors
293         // produced in golang.org/x/mod/module.CheckMod) implement an interface
294         // to make it easier to check for them? That would save us from having to
295         // move the modload errors into this package to avoid a package import cycle,
296         // and from having to export an error type for the errors produced in build.
297         if !isMatchErr && (nogoErr != nil || isScanErr) {
298                 stk.Push(path)
299                 defer stk.Pop()
300         }
301
302         p.Error = &PackageError{
303                 ImportStack: stk.Copy(),
304                 Pos:         pos,
305                 Err:         err,
306         }
307
308         if path != stk.Top() {
309                 p.Error.setPos(importPos)
310         }
311 }
312
313 // Resolve returns the resolved version of imports,
314 // which should be p.TestImports or p.XTestImports, NOT p.Imports.
315 // The imports in p.TestImports and p.XTestImports are not recursively
316 // loaded during the initial load of p, so they list the imports found in
317 // the source file, but most processing should be over the vendor-resolved
318 // import paths. We do this resolution lazily both to avoid file system work
319 // and because the eventual real load of the test imports (during 'go test')
320 // can produce better error messages if it starts with the original paths.
321 // The initial load of p loads all the non-test imports and rewrites
322 // the vendored paths, so nothing should ever call p.vendored(p.Imports).
323 func (p *Package) Resolve(imports []string) []string {
324         if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] {
325                 panic("internal error: p.Resolve(p.Imports) called")
326         }
327         seen := make(map[string]bool)
328         var all []string
329         for _, path := range imports {
330                 path = ResolveImportPath(p, path)
331                 if !seen[path] {
332                         seen[path] = true
333                         all = append(all, path)
334                 }
335         }
336         sort.Strings(all)
337         return all
338 }
339
340 // CoverVar holds the name of the generated coverage variables targeting the named file.
341 type CoverVar struct {
342         File string // local file name
343         Var  string // name of count struct
344 }
345
346 func (p *Package) copyBuild(pp *build.Package) {
347         p.Internal.Build = pp
348
349         if pp.PkgTargetRoot != "" && cfg.BuildPkgdir != "" {
350                 old := pp.PkgTargetRoot
351                 pp.PkgRoot = cfg.BuildPkgdir
352                 pp.PkgTargetRoot = cfg.BuildPkgdir
353                 pp.PkgObj = filepath.Join(cfg.BuildPkgdir, strings.TrimPrefix(pp.PkgObj, old))
354         }
355
356         p.Dir = pp.Dir
357         p.ImportPath = pp.ImportPath
358         p.ImportComment = pp.ImportComment
359         p.Name = pp.Name
360         p.Doc = pp.Doc
361         p.Root = pp.Root
362         p.ConflictDir = pp.ConflictDir
363         p.BinaryOnly = pp.BinaryOnly
364
365         // TODO? Target
366         p.Goroot = pp.Goroot
367         p.Standard = p.Goroot && p.ImportPath != "" && search.IsStandardImportPath(p.ImportPath)
368         p.GoFiles = pp.GoFiles
369         p.CgoFiles = pp.CgoFiles
370         p.IgnoredGoFiles = pp.IgnoredGoFiles
371         p.IgnoredOtherFiles = pp.IgnoredOtherFiles
372         p.CFiles = pp.CFiles
373         p.CXXFiles = pp.CXXFiles
374         p.MFiles = pp.MFiles
375         p.HFiles = pp.HFiles
376         p.FFiles = pp.FFiles
377         p.SFiles = pp.SFiles
378         p.SwigFiles = pp.SwigFiles
379         p.SwigCXXFiles = pp.SwigCXXFiles
380         p.SysoFiles = pp.SysoFiles
381         if cfg.BuildMSan {
382                 // There's no way for .syso files to be built both with and without
383                 // support for memory sanitizer. Assume they are built without,
384                 // and drop them.
385                 p.SysoFiles = nil
386         }
387         p.CgoCFLAGS = pp.CgoCFLAGS
388         p.CgoCPPFLAGS = pp.CgoCPPFLAGS
389         p.CgoCXXFLAGS = pp.CgoCXXFLAGS
390         p.CgoFFLAGS = pp.CgoFFLAGS
391         p.CgoLDFLAGS = pp.CgoLDFLAGS
392         p.CgoPkgConfig = pp.CgoPkgConfig
393         // We modify p.Imports in place, so make copy now.
394         p.Imports = make([]string, len(pp.Imports))
395         copy(p.Imports, pp.Imports)
396         p.Internal.RawImports = pp.Imports
397         p.TestGoFiles = pp.TestGoFiles
398         p.TestImports = pp.TestImports
399         p.XTestGoFiles = pp.XTestGoFiles
400         p.XTestImports = pp.XTestImports
401         if IgnoreImports {
402                 p.Imports = nil
403                 p.Internal.RawImports = nil
404                 p.TestImports = nil
405                 p.XTestImports = nil
406         }
407         p.EmbedPatterns = pp.EmbedPatterns
408         p.TestEmbedPatterns = pp.TestEmbedPatterns
409         p.XTestEmbedPatterns = pp.XTestEmbedPatterns
410 }
411
412 // A PackageError describes an error loading information about a package.
413 type PackageError struct {
414         ImportStack      []string // shortest path from package named on command line to this one
415         Pos              string   // position of error
416         Err              error    // the error itself
417         IsImportCycle    bool     // the error is an import cycle
418         Hard             bool     // whether the error is soft or hard; soft errors are ignored in some places
419         alwaysPrintStack bool     // whether to always print the ImportStack
420 }
421
422 func (p *PackageError) Error() string {
423         // TODO(#43696): decide when to print the stack or the position based on
424         // the error type and whether the package is in the main module.
425         // Document the rationale.
426         if p.Pos != "" && (len(p.ImportStack) == 0 || !p.alwaysPrintStack) {
427                 // Omit import stack. The full path to the file where the error
428                 // is the most important thing.
429                 return p.Pos + ": " + p.Err.Error()
430         }
431
432         // If the error is an ImportPathError, and the last path on the stack appears
433         // in the error message, omit that path from the stack to avoid repetition.
434         // If an ImportPathError wraps another ImportPathError that matches the
435         // last path on the stack, we don't omit the path. An error like
436         // "package A imports B: error loading C caused by B" would not be clearer
437         // if "imports B" were omitted.
438         if len(p.ImportStack) == 0 {
439                 return p.Err.Error()
440         }
441         var optpos string
442         if p.Pos != "" {
443                 optpos = "\n\t" + p.Pos
444         }
445         return "package " + strings.Join(p.ImportStack, "\n\timports ") + optpos + ": " + p.Err.Error()
446 }
447
448 func (p *PackageError) Unwrap() error { return p.Err }
449
450 // PackageError implements MarshalJSON so that Err is marshaled as a string
451 // and non-essential fields are omitted.
452 func (p *PackageError) MarshalJSON() ([]byte, error) {
453         perr := struct {
454                 ImportStack []string
455                 Pos         string
456                 Err         string
457         }{p.ImportStack, p.Pos, p.Err.Error()}
458         return json.Marshal(perr)
459 }
460
461 func (p *PackageError) setPos(posList []token.Position) {
462         if len(posList) == 0 {
463                 return
464         }
465         pos := posList[0]
466         pos.Filename = base.ShortPath(pos.Filename)
467         p.Pos = pos.String()
468 }
469
470 // ImportPathError is a type of error that prevents a package from being loaded
471 // for a given import path. When such a package is loaded, a *Package is
472 // returned with Err wrapping an ImportPathError: the error is attached to
473 // the imported package, not the importing package.
474 //
475 // The string returned by ImportPath must appear in the string returned by
476 // Error. Errors that wrap ImportPathError (such as PackageError) may omit
477 // the import path.
478 type ImportPathError interface {
479         error
480         ImportPath() string
481 }
482
483 var (
484         _ ImportPathError = (*importError)(nil)
485         _ ImportPathError = (*modload.ImportMissingError)(nil)
486         _ ImportPathError = (*modload.ImportMissingSumError)(nil)
487 )
488
489 type importError struct {
490         importPath string
491         err        error // created with fmt.Errorf
492 }
493
494 func ImportErrorf(path, format string, args ...interface{}) ImportPathError {
495         err := &importError{importPath: path, err: fmt.Errorf(format, args...)}
496         if errStr := err.Error(); !strings.Contains(errStr, path) {
497                 panic(fmt.Sprintf("path %q not in error %q", path, errStr))
498         }
499         return err
500 }
501
502 func (e *importError) Error() string {
503         return e.err.Error()
504 }
505
506 func (e *importError) Unwrap() error {
507         // Don't return e.err directly, since we're only wrapping an error if %w
508         // was passed to ImportErrorf.
509         return errors.Unwrap(e.err)
510 }
511
512 func (e *importError) ImportPath() string {
513         return e.importPath
514 }
515
516 // An ImportStack is a stack of import paths, possibly with the suffix " (test)" appended.
517 // The import path of a test package is the import path of the corresponding
518 // non-test package with the suffix "_test" added.
519 type ImportStack []string
520
521 func (s *ImportStack) Push(p string) {
522         *s = append(*s, p)
523 }
524
525 func (s *ImportStack) Pop() {
526         *s = (*s)[0 : len(*s)-1]
527 }
528
529 func (s *ImportStack) Copy() []string {
530         return append([]string{}, *s...)
531 }
532
533 func (s *ImportStack) Top() string {
534         if len(*s) == 0 {
535                 return ""
536         }
537         return (*s)[len(*s)-1]
538 }
539
540 // shorterThan reports whether sp is shorter than t.
541 // We use this to record the shortest import sequence
542 // that leads to a particular package.
543 func (sp *ImportStack) shorterThan(t []string) bool {
544         s := *sp
545         if len(s) != len(t) {
546                 return len(s) < len(t)
547         }
548         // If they are the same length, settle ties using string ordering.
549         for i := range s {
550                 if s[i] != t[i] {
551                         return s[i] < t[i]
552                 }
553         }
554         return false // they are equal
555 }
556
557 // packageCache is a lookup cache for LoadImport,
558 // so that if we look up a package multiple times
559 // we return the same pointer each time.
560 var packageCache = map[string]*Package{}
561
562 // ClearPackageCache clears the in-memory package cache and the preload caches.
563 // It is only for use by GOPATH-based "go get".
564 // TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
565 func ClearPackageCache() {
566         for name := range packageCache {
567                 delete(packageCache, name)
568         }
569         resolvedImportCache.Clear()
570         packageDataCache.Clear()
571 }
572
573 // ClearPackageCachePartial clears packages with the given import paths from the
574 // in-memory package cache and the preload caches. It is only for use by
575 // GOPATH-based "go get".
576 // TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
577 func ClearPackageCachePartial(args []string) {
578         shouldDelete := make(map[string]bool)
579         for _, arg := range args {
580                 shouldDelete[arg] = true
581                 if p := packageCache[arg]; p != nil {
582                         delete(packageCache, arg)
583                 }
584         }
585         resolvedImportCache.DeleteIf(func(key interface{}) bool {
586                 return shouldDelete[key.(importSpec).path]
587         })
588         packageDataCache.DeleteIf(func(key interface{}) bool {
589                 return shouldDelete[key.(string)]
590         })
591 }
592
593 // ReloadPackageNoFlags is like LoadImport but makes sure
594 // not to use the package cache.
595 // It is only for use by GOPATH-based "go get".
596 // TODO(rsc): When GOPATH-based "go get" is removed, delete this function.
597 func ReloadPackageNoFlags(arg string, stk *ImportStack) *Package {
598         p := packageCache[arg]
599         if p != nil {
600                 delete(packageCache, arg)
601                 resolvedImportCache.DeleteIf(func(key interface{}) bool {
602                         return key.(importSpec).path == p.ImportPath
603                 })
604                 packageDataCache.Delete(p.ImportPath)
605         }
606         return LoadImport(context.TODO(), arg, base.Cwd, nil, stk, nil, 0)
607 }
608
609 // dirToImportPath returns the pseudo-import path we use for a package
610 // outside the Go path. It begins with _/ and then contains the full path
611 // to the directory. If the package lives in c:\home\gopher\my\pkg then
612 // the pseudo-import path is _/c_/home/gopher/my/pkg.
613 // Using a pseudo-import path like this makes the ./ imports no longer
614 // a special case, so that all the code to deal with ordinary imports works
615 // automatically.
616 func dirToImportPath(dir string) string {
617         return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir)))
618 }
619
620 func makeImportValid(r rune) rune {
621         // Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport.
622         const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
623         if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
624                 return '_'
625         }
626         return r
627 }
628
629 // Mode flags for loadImport and download (in get.go).
630 const (
631         // ResolveImport means that loadImport should do import path expansion.
632         // That is, ResolveImport means that the import path came from
633         // a source file and has not been expanded yet to account for
634         // vendoring or possible module adjustment.
635         // Every import path should be loaded initially with ResolveImport,
636         // and then the expanded version (for example with the /vendor/ in it)
637         // gets recorded as the canonical import path. At that point, future loads
638         // of that package must not pass ResolveImport, because
639         // disallowVendor will reject direct use of paths containing /vendor/.
640         ResolveImport = 1 << iota
641
642         // ResolveModule is for download (part of "go get") and indicates
643         // that the module adjustment should be done, but not vendor adjustment.
644         ResolveModule
645
646         // GetTestDeps is for download (part of "go get") and indicates
647         // that test dependencies should be fetched too.
648         GetTestDeps
649 )
650
651 // LoadImport scans the directory named by path, which must be an import path,
652 // but possibly a local import path (an absolute file system path or one beginning
653 // with ./ or ../). A local relative path is interpreted relative to srcDir.
654 // It returns a *Package describing the package found in that directory.
655 // LoadImport does not set tool flags and should only be used by
656 // this package, as part of a bigger load operation, and by GOPATH-based "go get".
657 // TODO(rsc): When GOPATH-based "go get" is removed, unexport this function.
658 func LoadImport(ctx context.Context, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
659         return loadImport(ctx, nil, path, srcDir, parent, stk, importPos, mode)
660 }
661
662 func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
663         if path == "" {
664                 panic("LoadImport called with empty package path")
665         }
666
667         var parentPath, parentRoot string
668         parentIsStd := false
669         if parent != nil {
670                 parentPath = parent.ImportPath
671                 parentRoot = parent.Root
672                 parentIsStd = parent.Standard
673         }
674         bp, loaded, err := loadPackageData(path, parentPath, srcDir, parentRoot, parentIsStd, mode)
675         if loaded && pre != nil && !IgnoreImports {
676                 pre.preloadImports(bp.Imports, bp)
677         }
678         if bp == nil {
679                 if importErr, ok := err.(ImportPathError); !ok || importErr.ImportPath() != path {
680                         // Only add path to the error's import stack if it's not already present on the error.
681                         stk.Push(path)
682                         defer stk.Pop()
683                 }
684                 return &Package{
685                         PackagePublic: PackagePublic{
686                                 ImportPath: path,
687                                 Error: &PackageError{
688                                         ImportStack: stk.Copy(),
689                                         Err:         err,
690                                 },
691                         },
692                 }
693         }
694
695         importPath := bp.ImportPath
696         p := packageCache[importPath]
697         if p != nil {
698                 stk.Push(path)
699                 p = reusePackage(p, stk)
700                 stk.Pop()
701         } else {
702                 p = new(Package)
703                 p.Internal.Local = build.IsLocalImport(path)
704                 p.ImportPath = importPath
705                 packageCache[importPath] = p
706
707                 // Load package.
708                 // loadPackageData may return bp != nil even if an error occurs,
709                 // in order to return partial information.
710                 p.load(ctx, path, stk, importPos, bp, err)
711
712                 if !cfg.ModulesEnabled && path != cleanImport(path) {
713                         p.Error = &PackageError{
714                                 ImportStack: stk.Copy(),
715                                 Err:         ImportErrorf(path, "non-canonical import path %q: should be %q", path, pathpkg.Clean(path)),
716                         }
717                         p.Incomplete = true
718                         p.Error.setPos(importPos)
719                 }
720         }
721
722         // Checked on every import because the rules depend on the code doing the importing.
723         if perr := disallowInternal(srcDir, parent, parentPath, p, stk); perr != p {
724                 perr.Error.setPos(importPos)
725                 return perr
726         }
727         if mode&ResolveImport != 0 {
728                 if perr := disallowVendor(srcDir, path, parentPath, p, stk); perr != p {
729                         perr.Error.setPos(importPos)
730                         return perr
731                 }
732         }
733
734         if p.Name == "main" && parent != nil && parent.Dir != p.Dir {
735                 perr := *p
736                 perr.Error = &PackageError{
737                         ImportStack: stk.Copy(),
738                         Err:         ImportErrorf(path, "import %q is a program, not an importable package", path),
739                 }
740                 perr.Error.setPos(importPos)
741                 return &perr
742         }
743
744         if p.Internal.Local && parent != nil && !parent.Internal.Local {
745                 perr := *p
746                 var err error
747                 if path == "." {
748                         err = ImportErrorf(path, "%s: cannot import current directory", path)
749                 } else {
750                         err = ImportErrorf(path, "local import %q in non-local package", path)
751                 }
752                 perr.Error = &PackageError{
753                         ImportStack: stk.Copy(),
754                         Err:         err,
755                 }
756                 perr.Error.setPos(importPos)
757                 return &perr
758         }
759
760         return p
761 }
762
763 // loadPackageData loads information needed to construct a *Package. The result
764 // is cached, and later calls to loadPackageData for the same package will return
765 // the same data.
766 //
767 // loadPackageData returns a non-nil package even if err is non-nil unless
768 // the package path is malformed (for example, the path contains "mod/" or "@").
769 //
770 // loadPackageData returns a boolean, loaded, which is true if this is the
771 // first time the package was loaded. Callers may preload imports in this case.
772 func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd bool, mode int) (bp *build.Package, loaded bool, err error) {
773         if path == "" {
774                 panic("loadPackageData called with empty package path")
775         }
776
777         if strings.HasPrefix(path, "mod/") {
778                 // Paths beginning with "mod/" might accidentally
779                 // look in the module cache directory tree in $GOPATH/pkg/mod/.
780                 // This prefix is owned by the Go core for possible use in the
781                 // standard library (since it does not begin with a domain name),
782                 // so it's OK to disallow entirely.
783                 return nil, false, fmt.Errorf("disallowed import path %q", path)
784         }
785
786         if strings.Contains(path, "@") {
787                 return nil, false, errors.New("can only use path@version syntax with 'go get' and 'go install' in module-aware mode")
788         }
789
790         // Determine canonical package path and directory.
791         // For a local import the identifier is the pseudo-import path
792         // we create from the full directory to the package.
793         // Otherwise it is the usual import path.
794         // For vendored imports, it is the expanded form.
795         //
796         // Note that when modules are enabled, local import paths are normally
797         // canonicalized by modload.LoadPackages before now. However, if there's an
798         // error resolving a local path, it will be returned untransformed
799         // so that 'go list -e' reports something useful.
800         importKey := importSpec{
801                 path:        path,
802                 parentPath:  parentPath,
803                 parentDir:   parentDir,
804                 parentRoot:  parentRoot,
805                 parentIsStd: parentIsStd,
806                 mode:        mode,
807         }
808         r := resolvedImportCache.Do(importKey, func() interface{} {
809                 var r resolvedImport
810                 if build.IsLocalImport(path) {
811                         r.dir = filepath.Join(parentDir, path)
812                         r.path = dirToImportPath(r.dir)
813                 } else if cfg.ModulesEnabled {
814                         r.dir, r.path, r.err = modload.Lookup(parentPath, parentIsStd, path)
815                 } else if mode&ResolveImport != 0 {
816                         // We do our own path resolution, because we want to
817                         // find out the key to use in packageCache without the
818                         // overhead of repeated calls to buildContext.Import.
819                         // The code is also needed in a few other places anyway.
820                         r.path = resolveImportPath(path, parentPath, parentDir, parentRoot, parentIsStd)
821                 } else if mode&ResolveModule != 0 {
822                         r.path = moduleImportPath(path, parentPath, parentDir, parentRoot)
823                 }
824                 if r.path == "" {
825                         r.path = path
826                 }
827                 return r
828         }).(resolvedImport)
829         // Invariant: r.path is set to the resolved import path. If the path cannot
830         // be resolved, r.path is set to path, the source import path.
831         // r.path is never empty.
832
833         // Load the package from its directory. If we already found the package's
834         // directory when resolving its import path, use that.
835         data := packageDataCache.Do(r.path, func() interface{} {
836                 loaded = true
837                 var data packageData
838                 if r.dir != "" {
839                         var buildMode build.ImportMode
840                         if !cfg.ModulesEnabled {
841                                 buildMode = build.ImportComment
842                         }
843                         data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode)
844                         if data.p.Root == "" && cfg.ModulesEnabled {
845                                 if info := modload.PackageModuleInfo(path); info != nil {
846                                         data.p.Root = info.Dir
847                                 }
848                         }
849                 } else if r.err != nil {
850                         data.p = new(build.Package)
851                         data.err = r.err
852                 } else if cfg.ModulesEnabled && path != "unsafe" {
853                         data.p = new(build.Package)
854                         data.err = fmt.Errorf("unknown import path %q: internal error: module loader did not resolve import", r.path)
855                 } else {
856                         buildMode := build.ImportComment
857                         if mode&ResolveImport == 0 || r.path != path {
858                                 // Not vendoring, or we already found the vendored path.
859                                 buildMode |= build.IgnoreVendor
860                         }
861                         data.p, data.err = cfg.BuildContext.Import(r.path, parentDir, buildMode)
862                 }
863                 data.p.ImportPath = r.path
864
865                 // Set data.p.BinDir in cases where go/build.Context.Import
866                 // may give us a path we don't want.
867                 if !data.p.Goroot {
868                         if cfg.GOBIN != "" {
869                                 data.p.BinDir = cfg.GOBIN
870                         } else if cfg.ModulesEnabled {
871                                 data.p.BinDir = modload.BinDir()
872                         }
873                 }
874
875                 if !cfg.ModulesEnabled && data.err == nil &&
876                         data.p.ImportComment != "" && data.p.ImportComment != path &&
877                         !strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") {
878                         data.err = fmt.Errorf("code in directory %s expects import %q", data.p.Dir, data.p.ImportComment)
879                 }
880                 return data
881         }).(packageData)
882
883         return data.p, loaded, data.err
884 }
885
886 // importSpec describes an import declaration in source code. It is used as a
887 // cache key for resolvedImportCache.
888 type importSpec struct {
889         path                              string
890         parentPath, parentDir, parentRoot string
891         parentIsStd                       bool
892         mode                              int
893 }
894
895 // resolvedImport holds a canonical identifier for a package. It may also contain
896 // a path to the package's directory and an error if one occurred. resolvedImport
897 // is the value type in resolvedImportCache.
898 type resolvedImport struct {
899         path, dir string
900         err       error
901 }
902
903 // packageData holds information loaded from a package. It is the value type
904 // in packageDataCache.
905 type packageData struct {
906         p   *build.Package
907         err error
908 }
909
910 // resolvedImportCache maps import strings (importSpec) to canonical package names
911 // (resolvedImport).
912 var resolvedImportCache par.Cache
913
914 // packageDataCache maps canonical package names (string) to package metadata
915 // (packageData).
916 var packageDataCache par.Cache
917
918 // preloadWorkerCount is the number of concurrent goroutines that can load
919 // packages. Experimentally, there are diminishing returns with more than
920 // 4 workers. This was measured on the following machines.
921 //
922 // * MacBookPro with a 4-core Intel Core i7 CPU
923 // * Linux workstation with 6-core Intel Xeon CPU
924 // * Linux workstation with 24-core Intel Xeon CPU
925 //
926 // It is very likely (though not confirmed) that this workload is limited
927 // by memory bandwidth. We don't have a good way to determine the number of
928 // workers that would saturate the bus though, so runtime.GOMAXPROCS
929 // seems like a reasonable default.
930 var preloadWorkerCount = runtime.GOMAXPROCS(0)
931
932 // preload holds state for managing concurrent preloading of package data.
933 //
934 // A preload should be created with newPreload before loading a large
935 // package graph. flush must be called when package loading is complete
936 // to ensure preload goroutines are no longer active. This is necessary
937 // because of global mutable state that cannot safely be read and written
938 // concurrently. In particular, packageDataCache may be cleared by "go get"
939 // in GOPATH mode, and modload.loaded (accessed via modload.Lookup) may be
940 // modified by modload.LoadPackages.
941 type preload struct {
942         cancel chan struct{}
943         sema   chan struct{}
944 }
945
946 // newPreload creates a new preloader. flush must be called later to avoid
947 // accessing global state while it is being modified.
948 func newPreload() *preload {
949         pre := &preload{
950                 cancel: make(chan struct{}),
951                 sema:   make(chan struct{}, preloadWorkerCount),
952         }
953         return pre
954 }
955
956 // preloadMatches loads data for package paths matched by patterns.
957 // When preloadMatches returns, some packages may not be loaded yet, but
958 // loadPackageData and loadImport are always safe to call.
959 func (pre *preload) preloadMatches(matches []*search.Match) {
960         for _, m := range matches {
961                 for _, pkg := range m.Pkgs {
962                         select {
963                         case <-pre.cancel:
964                                 return
965                         case pre.sema <- struct{}{}:
966                                 go func(pkg string) {
967                                         mode := 0 // don't use vendoring or module import resolution
968                                         bp, loaded, err := loadPackageData(pkg, "", base.Cwd, "", false, mode)
969                                         <-pre.sema
970                                         if bp != nil && loaded && err == nil && !IgnoreImports {
971                                                 pre.preloadImports(bp.Imports, bp)
972                                         }
973                                 }(pkg)
974                         }
975                 }
976         }
977 }
978
979 // preloadImports queues a list of imports for preloading.
980 // When preloadImports returns, some packages may not be loaded yet,
981 // but loadPackageData and loadImport are always safe to call.
982 func (pre *preload) preloadImports(imports []string, parent *build.Package) {
983         parentIsStd := parent.Goroot && parent.ImportPath != "" && search.IsStandardImportPath(parent.ImportPath)
984         for _, path := range imports {
985                 if path == "C" || path == "unsafe" {
986                         continue
987                 }
988                 select {
989                 case <-pre.cancel:
990                         return
991                 case pre.sema <- struct{}{}:
992                         go func(path string) {
993                                 bp, loaded, err := loadPackageData(path, parent.ImportPath, parent.Dir, parent.Root, parentIsStd, ResolveImport)
994                                 <-pre.sema
995                                 if bp != nil && loaded && err == nil && !IgnoreImports {
996                                         pre.preloadImports(bp.Imports, bp)
997                                 }
998                         }(path)
999                 }
1000         }
1001 }
1002
1003 // flush stops pending preload operations. flush blocks until preload calls to
1004 // loadPackageData have completed. The preloader will not make any new calls
1005 // to loadPackageData.
1006 func (pre *preload) flush() {
1007         // flush is usually deferred.
1008         // Don't hang program waiting for workers on panic.
1009         if v := recover(); v != nil {
1010                 panic(v)
1011         }
1012
1013         close(pre.cancel)
1014         for i := 0; i < preloadWorkerCount; i++ {
1015                 pre.sema <- struct{}{}
1016         }
1017 }
1018
1019 func cleanImport(path string) string {
1020         orig := path
1021         path = pathpkg.Clean(path)
1022         if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") {
1023                 path = "./" + path
1024         }
1025         return path
1026 }
1027
1028 var isDirCache par.Cache
1029
1030 func isDir(path string) bool {
1031         return isDirCache.Do(path, func() interface{} {
1032                 fi, err := fsys.Stat(path)
1033                 return err == nil && fi.IsDir()
1034         }).(bool)
1035 }
1036
1037 // ResolveImportPath returns the true meaning of path when it appears in parent.
1038 // There are two different resolutions applied.
1039 // First, there is Go 1.5 vendoring (golang.org/s/go15vendor).
1040 // If vendor expansion doesn't trigger, then the path is also subject to
1041 // Go 1.11 module legacy conversion (golang.org/issue/25069).
1042 func ResolveImportPath(parent *Package, path string) (found string) {
1043         var parentPath, parentDir, parentRoot string
1044         parentIsStd := false
1045         if parent != nil {
1046                 parentPath = parent.ImportPath
1047                 parentDir = parent.Dir
1048                 parentRoot = parent.Root
1049                 parentIsStd = parent.Standard
1050         }
1051         return resolveImportPath(path, parentPath, parentDir, parentRoot, parentIsStd)
1052 }
1053
1054 func resolveImportPath(path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) {
1055         if cfg.ModulesEnabled {
1056                 if _, p, e := modload.Lookup(parentPath, parentIsStd, path); e == nil {
1057                         return p
1058                 }
1059                 return path
1060         }
1061         found = vendoredImportPath(path, parentPath, parentDir, parentRoot)
1062         if found != path {
1063                 return found
1064         }
1065         return moduleImportPath(path, parentPath, parentDir, parentRoot)
1066 }
1067
1068 // dirAndRoot returns the source directory and workspace root
1069 // for the package p, guaranteeing that root is a path prefix of dir.
1070 func dirAndRoot(path string, dir, root string) (string, string) {
1071         origDir, origRoot := dir, root
1072         dir = filepath.Clean(dir)
1073         root = filepath.Join(root, "src")
1074         if !str.HasFilePathPrefix(dir, root) || path != "command-line-arguments" && filepath.Join(root, path) != dir {
1075                 // Look for symlinks before reporting error.
1076                 dir = expandPath(dir)
1077                 root = expandPath(root)
1078         }
1079
1080         if !str.HasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator || path != "command-line-arguments" && !build.IsLocalImport(path) && filepath.Join(root, path) != dir {
1081                 base.Fatalf("unexpected directory layout:\n"+
1082                         "       import path: %s\n"+
1083                         "       root: %s\n"+
1084                         "       dir: %s\n"+
1085                         "       expand root: %s\n"+
1086                         "       expand dir: %s\n"+
1087                         "       separator: %s",
1088                         path,
1089                         filepath.Join(origRoot, "src"),
1090                         filepath.Clean(origDir),
1091                         origRoot,
1092                         origDir,
1093                         string(filepath.Separator))
1094         }
1095
1096         return dir, root
1097 }
1098
1099 // vendoredImportPath returns the vendor-expansion of path when it appears in parent.
1100 // If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path,
1101 // x/vendor/path, vendor/path, or else stay path if none of those exist.
1102 // vendoredImportPath returns the expanded path or, if no expansion is found, the original.
1103 func vendoredImportPath(path, parentPath, parentDir, parentRoot string) (found string) {
1104         if parentRoot == "" {
1105                 return path
1106         }
1107
1108         dir, root := dirAndRoot(parentPath, parentDir, parentRoot)
1109
1110         vpath := "vendor/" + path
1111         for i := len(dir); i >= len(root); i-- {
1112                 if i < len(dir) && dir[i] != filepath.Separator {
1113                         continue
1114                 }
1115                 // Note: checking for the vendor directory before checking
1116                 // for the vendor/path directory helps us hit the
1117                 // isDir cache more often. It also helps us prepare a more useful
1118                 // list of places we looked, to report when an import is not found.
1119                 if !isDir(filepath.Join(dir[:i], "vendor")) {
1120                         continue
1121                 }
1122                 targ := filepath.Join(dir[:i], vpath)
1123                 if isDir(targ) && hasGoFiles(targ) {
1124                         importPath := parentPath
1125                         if importPath == "command-line-arguments" {
1126                                 // If parent.ImportPath is 'command-line-arguments'.
1127                                 // set to relative directory to root (also chopped root directory)
1128                                 importPath = dir[len(root)+1:]
1129                         }
1130                         // We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy.
1131                         // We know the import path for parent's dir.
1132                         // We chopped off some number of path elements and
1133                         // added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path.
1134                         // Now we want to know the import path for that directory.
1135                         // Construct it by chopping the same number of path elements
1136                         // (actually the same number of bytes) from parent's import path
1137                         // and then append /vendor/path.
1138                         chopped := len(dir) - i
1139                         if chopped == len(importPath)+1 {
1140                                 // We walked up from c:\gopath\src\foo\bar
1141                                 // and found c:\gopath\src\vendor\path.
1142                                 // We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7).
1143                                 // Use "vendor/path" without any prefix.
1144                                 return vpath
1145                         }
1146                         return importPath[:len(importPath)-chopped] + "/" + vpath
1147                 }
1148         }
1149         return path
1150 }
1151
1152 var (
1153         modulePrefix   = []byte("\nmodule ")
1154         goModPathCache par.Cache
1155 )
1156
1157 // goModPath returns the module path in the go.mod in dir, if any.
1158 func goModPath(dir string) (path string) {
1159         return goModPathCache.Do(dir, func() interface{} {
1160                 data, err := os.ReadFile(filepath.Join(dir, "go.mod"))
1161                 if err != nil {
1162                         return ""
1163                 }
1164                 var i int
1165                 if bytes.HasPrefix(data, modulePrefix[1:]) {
1166                         i = 0
1167                 } else {
1168                         i = bytes.Index(data, modulePrefix)
1169                         if i < 0 {
1170                                 return ""
1171                         }
1172                         i++
1173                 }
1174                 line := data[i:]
1175
1176                 // Cut line at \n, drop trailing \r if present.
1177                 if j := bytes.IndexByte(line, '\n'); j >= 0 {
1178                         line = line[:j]
1179                 }
1180                 if line[len(line)-1] == '\r' {
1181                         line = line[:len(line)-1]
1182                 }
1183                 line = line[len("module "):]
1184
1185                 // If quoted, unquote.
1186                 path = strings.TrimSpace(string(line))
1187                 if path != "" && path[0] == '"' {
1188                         s, err := strconv.Unquote(path)
1189                         if err != nil {
1190                                 return ""
1191                         }
1192                         path = s
1193                 }
1194                 return path
1195         }).(string)
1196 }
1197
1198 // findVersionElement returns the slice indices of the final version element /vN in path.
1199 // If there is no such element, it returns -1, -1.
1200 func findVersionElement(path string) (i, j int) {
1201         j = len(path)
1202         for i = len(path) - 1; i >= 0; i-- {
1203                 if path[i] == '/' {
1204                         if isVersionElement(path[i+1 : j]) {
1205                                 return i, j
1206                         }
1207                         j = i
1208                 }
1209         }
1210         return -1, -1
1211 }
1212
1213 // isVersionElement reports whether s is a well-formed path version element:
1214 // v2, v3, v10, etc, but not v0, v05, v1.
1215 func isVersionElement(s string) bool {
1216         if len(s) < 2 || s[0] != 'v' || s[1] == '0' || s[1] == '1' && len(s) == 2 {
1217                 return false
1218         }
1219         for i := 1; i < len(s); i++ {
1220                 if s[i] < '0' || '9' < s[i] {
1221                         return false
1222                 }
1223         }
1224         return true
1225 }
1226
1227 // moduleImportPath translates import paths found in go modules
1228 // back down to paths that can be resolved in ordinary builds.
1229 //
1230 // Define “new” code as code with a go.mod file in the same directory
1231 // or a parent directory. If an import in new code says x/y/v2/z but
1232 // x/y/v2/z does not exist and x/y/go.mod says “module x/y/v2”,
1233 // then go build will read the import as x/y/z instead.
1234 // See golang.org/issue/25069.
1235 func moduleImportPath(path, parentPath, parentDir, parentRoot string) (found string) {
1236         if parentRoot == "" {
1237                 return path
1238         }
1239
1240         // If there are no vN elements in path, leave it alone.
1241         // (The code below would do the same, but only after
1242         // some other file system accesses that we can avoid
1243         // here by returning early.)
1244         if i, _ := findVersionElement(path); i < 0 {
1245                 return path
1246         }
1247
1248         dir, root := dirAndRoot(parentPath, parentDir, parentRoot)
1249
1250         // Consider dir and parents, up to and including root.
1251         for i := len(dir); i >= len(root); i-- {
1252                 if i < len(dir) && dir[i] != filepath.Separator {
1253                         continue
1254                 }
1255                 if goModPath(dir[:i]) != "" {
1256                         goto HaveGoMod
1257                 }
1258         }
1259         // This code is not in a tree with a go.mod,
1260         // so apply no changes to the path.
1261         return path
1262
1263 HaveGoMod:
1264         // This import is in a tree with a go.mod.
1265         // Allow it to refer to code in GOPATH/src/x/y/z as x/y/v2/z
1266         // if GOPATH/src/x/y/go.mod says module "x/y/v2",
1267
1268         // If x/y/v2/z exists, use it unmodified.
1269         if bp, _ := cfg.BuildContext.Import(path, "", build.IgnoreVendor); bp.Dir != "" {
1270                 return path
1271         }
1272
1273         // Otherwise look for a go.mod supplying a version element.
1274         // Some version-like elements may appear in paths but not
1275         // be module versions; we skip over those to look for module
1276         // versions. For example the module m/v2 might have a
1277         // package m/v2/api/v1/foo.
1278         limit := len(path)
1279         for limit > 0 {
1280                 i, j := findVersionElement(path[:limit])
1281                 if i < 0 {
1282                         return path
1283                 }
1284                 if bp, _ := cfg.BuildContext.Import(path[:i], "", build.IgnoreVendor); bp.Dir != "" {
1285                         if mpath := goModPath(bp.Dir); mpath != "" {
1286                                 // Found a valid go.mod file, so we're stopping the search.
1287                                 // If the path is m/v2/p and we found m/go.mod that says
1288                                 // "module m/v2", then we return "m/p".
1289                                 if mpath == path[:j] {
1290                                         return path[:i] + path[j:]
1291                                 }
1292                                 // Otherwise just return the original path.
1293                                 // We didn't find anything worth rewriting,
1294                                 // and the go.mod indicates that we should
1295                                 // not consider parent directories.
1296                                 return path
1297                         }
1298                 }
1299                 limit = i
1300         }
1301         return path
1302 }
1303
1304 // hasGoFiles reports whether dir contains any files with names ending in .go.
1305 // For a vendor check we must exclude directories that contain no .go files.
1306 // Otherwise it is not possible to vendor just a/b/c and still import the
1307 // non-vendored a/b. See golang.org/issue/13832.
1308 func hasGoFiles(dir string) bool {
1309         files, _ := os.ReadDir(dir)
1310         for _, f := range files {
1311                 if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") {
1312                         return true
1313                 }
1314         }
1315         return false
1316 }
1317
1318 // reusePackage reuses package p to satisfy the import at the top
1319 // of the import stack stk. If this use causes an import loop,
1320 // reusePackage updates p's error information to record the loop.
1321 func reusePackage(p *Package, stk *ImportStack) *Package {
1322         // We use p.Internal.Imports==nil to detect a package that
1323         // is in the midst of its own loadPackage call
1324         // (all the recursion below happens before p.Internal.Imports gets set).
1325         if p.Internal.Imports == nil {
1326                 if p.Error == nil {
1327                         p.Error = &PackageError{
1328                                 ImportStack:   stk.Copy(),
1329                                 Err:           errors.New("import cycle not allowed"),
1330                                 IsImportCycle: true,
1331                         }
1332                 }
1333                 p.Incomplete = true
1334         }
1335         // Don't rewrite the import stack in the error if we have an import cycle.
1336         // If we do, we'll lose the path that describes the cycle.
1337         if p.Error != nil && !p.Error.IsImportCycle && stk.shorterThan(p.Error.ImportStack) {
1338                 p.Error.ImportStack = stk.Copy()
1339         }
1340         return p
1341 }
1342
1343 // disallowInternal checks that srcDir (containing package importerPath, if non-empty)
1344 // is allowed to import p.
1345 // If the import is allowed, disallowInternal returns the original package p.
1346 // If not, it returns a new package containing just an appropriate error.
1347 func disallowInternal(srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *Package {
1348         // golang.org/s/go14internal:
1349         // An import of a path containing the element “internal”
1350         // is disallowed if the importing code is outside the tree
1351         // rooted at the parent of the “internal” directory.
1352
1353         // There was an error loading the package; stop here.
1354         if p.Error != nil {
1355                 return p
1356         }
1357
1358         // The generated 'testmain' package is allowed to access testing/internal/...,
1359         // as if it were generated into the testing directory tree
1360         // (it's actually in a temporary directory outside any Go tree).
1361         // This cleans up a former kludge in passing functionality to the testing package.
1362         if str.HasPathPrefix(p.ImportPath, "testing/internal") && importerPath == "testmain" {
1363                 return p
1364         }
1365
1366         // We can't check standard packages with gccgo.
1367         if cfg.BuildContext.Compiler == "gccgo" && p.Standard {
1368                 return p
1369         }
1370
1371         // The sort package depends on internal/reflectlite, but during bootstrap
1372         // the path rewriting causes the normal internal checks to fail.
1373         // Instead, just ignore the internal rules during bootstrap.
1374         if p.Standard && strings.HasPrefix(importerPath, "bootstrap/") {
1375                 return p
1376         }
1377
1378         // importerPath is empty: we started
1379         // with a name given on the command line, not an
1380         // import. Anything listed on the command line is fine.
1381         if importerPath == "" {
1382                 return p
1383         }
1384
1385         // Check for "internal" element: three cases depending on begin of string and/or end of string.
1386         i, ok := findInternal(p.ImportPath)
1387         if !ok {
1388                 return p
1389         }
1390
1391         // Internal is present.
1392         // Map import path back to directory corresponding to parent of internal.
1393         if i > 0 {
1394                 i-- // rewind over slash in ".../internal"
1395         }
1396
1397         if p.Module == nil {
1398                 parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]
1399
1400                 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1401                         return p
1402                 }
1403
1404                 // Look for symlinks before reporting error.
1405                 srcDir = expandPath(srcDir)
1406                 parent = expandPath(parent)
1407                 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1408                         return p
1409                 }
1410         } else {
1411                 // p is in a module, so make it available based on the importer's import path instead
1412                 // of the file path (https://golang.org/issue/23970).
1413                 if importer.Internal.CmdlineFiles {
1414                         // The importer is a list of command-line files.
1415                         // Pretend that the import path is the import path of the
1416                         // directory containing them.
1417                         // If the directory is outside the main module, this will resolve to ".",
1418                         // which is not a prefix of any valid module.
1419                         importerPath = modload.DirImportPath(importer.Dir)
1420                 }
1421                 parentOfInternal := p.ImportPath[:i]
1422                 if str.HasPathPrefix(importerPath, parentOfInternal) {
1423                         return p
1424                 }
1425         }
1426
1427         // Internal is present, and srcDir is outside parent's tree. Not allowed.
1428         perr := *p
1429         perr.Error = &PackageError{
1430                 alwaysPrintStack: true,
1431                 ImportStack:      stk.Copy(),
1432                 Err:              ImportErrorf(p.ImportPath, "use of internal package "+p.ImportPath+" not allowed"),
1433         }
1434         perr.Incomplete = true
1435         return &perr
1436 }
1437
1438 // findInternal looks for the final "internal" path element in the given import path.
1439 // If there isn't one, findInternal returns ok=false.
1440 // Otherwise, findInternal returns ok=true and the index of the "internal".
1441 func findInternal(path string) (index int, ok bool) {
1442         // Three cases, depending on internal at start/end of string or not.
1443         // The order matters: we must return the index of the final element,
1444         // because the final one produces the most restrictive requirement
1445         // on the importer.
1446         switch {
1447         case strings.HasSuffix(path, "/internal"):
1448                 return len(path) - len("internal"), true
1449         case strings.Contains(path, "/internal/"):
1450                 return strings.LastIndex(path, "/internal/") + 1, true
1451         case path == "internal", strings.HasPrefix(path, "internal/"):
1452                 return 0, true
1453         }
1454         return 0, false
1455 }
1456
1457 // disallowVendor checks that srcDir is allowed to import p as path.
1458 // If the import is allowed, disallowVendor returns the original package p.
1459 // If not, it returns a new package containing just an appropriate error.
1460 func disallowVendor(srcDir string, path string, importerPath string, p *Package, stk *ImportStack) *Package {
1461         // If the importerPath is empty, we started
1462         // with a name given on the command line, not an
1463         // import. Anything listed on the command line is fine.
1464         if importerPath == "" {
1465                 return p
1466         }
1467
1468         if perr := disallowVendorVisibility(srcDir, p, importerPath, stk); perr != p {
1469                 return perr
1470         }
1471
1472         // Paths like x/vendor/y must be imported as y, never as x/vendor/y.
1473         if i, ok := FindVendor(path); ok {
1474                 perr := *p
1475                 perr.Error = &PackageError{
1476                         ImportStack: stk.Copy(),
1477                         Err:         ImportErrorf(path, "%s must be imported as %s", path, path[i+len("vendor/"):]),
1478                 }
1479                 perr.Incomplete = true
1480                 return &perr
1481         }
1482
1483         return p
1484 }
1485
1486 // disallowVendorVisibility checks that srcDir is allowed to import p.
1487 // The rules are the same as for /internal/ except that a path ending in /vendor
1488 // is not subject to the rules, only subdirectories of vendor.
1489 // This allows people to have packages and commands named vendor,
1490 // for maximal compatibility with existing source trees.
1491 func disallowVendorVisibility(srcDir string, p *Package, importerPath string, stk *ImportStack) *Package {
1492         // The stack does not include p.ImportPath.
1493         // If there's nothing on the stack, we started
1494         // with a name given on the command line, not an
1495         // import. Anything listed on the command line is fine.
1496         if importerPath == "" {
1497                 return p
1498         }
1499
1500         // Check for "vendor" element.
1501         i, ok := FindVendor(p.ImportPath)
1502         if !ok {
1503                 return p
1504         }
1505
1506         // Vendor is present.
1507         // Map import path back to directory corresponding to parent of vendor.
1508         if i > 0 {
1509                 i-- // rewind over slash in ".../vendor"
1510         }
1511         truncateTo := i + len(p.Dir) - len(p.ImportPath)
1512         if truncateTo < 0 || len(p.Dir) < truncateTo {
1513                 return p
1514         }
1515         parent := p.Dir[:truncateTo]
1516         if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1517                 return p
1518         }
1519
1520         // Look for symlinks before reporting error.
1521         srcDir = expandPath(srcDir)
1522         parent = expandPath(parent)
1523         if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1524                 return p
1525         }
1526
1527         // Vendor is present, and srcDir is outside parent's tree. Not allowed.
1528         perr := *p
1529         perr.Error = &PackageError{
1530                 ImportStack: stk.Copy(),
1531                 Err:         errors.New("use of vendored package not allowed"),
1532         }
1533         perr.Incomplete = true
1534         return &perr
1535 }
1536
1537 // FindVendor looks for the last non-terminating "vendor" path element in the given import path.
1538 // If there isn't one, FindVendor returns ok=false.
1539 // Otherwise, FindVendor returns ok=true and the index of the "vendor".
1540 //
1541 // Note that terminating "vendor" elements don't count: "x/vendor" is its own package,
1542 // not the vendored copy of an import "" (the empty import path).
1543 // This will allow people to have packages or commands named vendor.
1544 // This may help reduce breakage, or it may just be confusing. We'll see.
1545 func FindVendor(path string) (index int, ok bool) {
1546         // Two cases, depending on internal at start of string or not.
1547         // The order matters: we must return the index of the final element,
1548         // because the final one is where the effective import path starts.
1549         switch {
1550         case strings.Contains(path, "/vendor/"):
1551                 return strings.LastIndex(path, "/vendor/") + 1, true
1552         case strings.HasPrefix(path, "vendor/"):
1553                 return 0, true
1554         }
1555         return 0, false
1556 }
1557
1558 type TargetDir int
1559
1560 const (
1561         ToTool    TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*)
1562         ToBin                      // to bin dir inside package root (default for non-cmd/*)
1563         StalePath                  // an old import path; fail to build
1564 )
1565
1566 // InstallTargetDir reports the target directory for installing the command p.
1567 func InstallTargetDir(p *Package) TargetDir {
1568         if strings.HasPrefix(p.ImportPath, "code.google.com/p/go.tools/cmd/") {
1569                 return StalePath
1570         }
1571         if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" {
1572                 switch p.ImportPath {
1573                 case "cmd/go", "cmd/gofmt":
1574                         return ToBin
1575                 }
1576                 return ToTool
1577         }
1578         return ToBin
1579 }
1580
1581 var cgoExclude = map[string]bool{
1582         "runtime/cgo": true,
1583 }
1584
1585 var cgoSyscallExclude = map[string]bool{
1586         "runtime/cgo":  true,
1587         "runtime/race": true,
1588         "runtime/msan": true,
1589 }
1590
1591 var foldPath = make(map[string]string)
1592
1593 // exeFromImportPath returns an executable name
1594 // for a package using the import path.
1595 //
1596 // The executable name is the last element of the import path.
1597 // In module-aware mode, an additional rule is used on import paths
1598 // consisting of two or more path elements. If the last element is
1599 // a vN path element specifying the major version, then the
1600 // second last element of the import path is used instead.
1601 func (p *Package) exeFromImportPath() string {
1602         _, elem := pathpkg.Split(p.ImportPath)
1603         if cfg.ModulesEnabled {
1604                 // If this is example.com/mycmd/v2, it's more useful to
1605                 // install it as mycmd than as v2. See golang.org/issue/24667.
1606                 if elem != p.ImportPath && isVersionElement(elem) {
1607                         _, elem = pathpkg.Split(pathpkg.Dir(p.ImportPath))
1608                 }
1609         }
1610         return elem
1611 }
1612
1613 // exeFromFiles returns an executable name for a package
1614 // using the first element in GoFiles or CgoFiles collections without the prefix.
1615 //
1616 // Returns empty string in case of empty collection.
1617 func (p *Package) exeFromFiles() string {
1618         var src string
1619         if len(p.GoFiles) > 0 {
1620                 src = p.GoFiles[0]
1621         } else if len(p.CgoFiles) > 0 {
1622                 src = p.CgoFiles[0]
1623         } else {
1624                 return ""
1625         }
1626         _, elem := filepath.Split(src)
1627         return elem[:len(elem)-len(".go")]
1628 }
1629
1630 // DefaultExecName returns the default executable name for a package
1631 func (p *Package) DefaultExecName() string {
1632         if p.Internal.CmdlineFiles {
1633                 return p.exeFromFiles()
1634         }
1635         return p.exeFromImportPath()
1636 }
1637
1638 // load populates p using information from bp, err, which should
1639 // be the result of calling build.Context.Import.
1640 // stk contains the import stack, not including path itself.
1641 func (p *Package) load(ctx context.Context, path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) {
1642         p.copyBuild(bp)
1643
1644         // The localPrefix is the path we interpret ./ imports relative to.
1645         // Synthesized main packages sometimes override this.
1646         if p.Internal.Local {
1647                 p.Internal.LocalPrefix = dirToImportPath(p.Dir)
1648         }
1649
1650         // setError sets p.Error if it hasn't already been set. We may proceed
1651         // after encountering some errors so that 'go list -e' has more complete
1652         // output. If there's more than one error, we should report the first.
1653         setError := func(err error) {
1654                 if p.Error == nil {
1655                         p.Error = &PackageError{
1656                                 ImportStack: stk.Copy(),
1657                                 Err:         err,
1658                         }
1659
1660                         // Add the importer's position information if the import position exists, and
1661                         // the current package being examined is the importer.
1662                         // If we have not yet accepted package p onto the import stack,
1663                         // then the cause of the error is not within p itself: the error
1664                         // must be either in an explicit command-line argument,
1665                         // or on the importer side (indicated by a non-empty importPos).
1666                         if path != stk.Top() && len(importPos) > 0 {
1667                                 p.Error.setPos(importPos)
1668                         }
1669                 }
1670         }
1671
1672         if err != nil {
1673                 p.Incomplete = true
1674                 p.setLoadPackageDataError(err, path, stk, importPos)
1675         }
1676
1677         useBindir := p.Name == "main"
1678         if !p.Standard {
1679                 switch cfg.BuildBuildmode {
1680                 case "c-archive", "c-shared", "plugin":
1681                         useBindir = false
1682                 }
1683         }
1684
1685         if useBindir {
1686                 // Report an error when the old code.google.com/p/go.tools paths are used.
1687                 if InstallTargetDir(p) == StalePath {
1688                         // TODO(matloob): remove this branch, and StalePath itself. code.google.com/p/go is so
1689                         // old, even this code checking for it is stale now!
1690                         newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1)
1691                         e := ImportErrorf(p.ImportPath, "the %v command has moved; use %v instead.", p.ImportPath, newPath)
1692                         setError(e)
1693                         return
1694                 }
1695                 elem := p.DefaultExecName()
1696                 full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem
1697                 if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH {
1698                         // Install cross-compiled binaries to subdirectories of bin.
1699                         elem = full
1700                 }
1701                 if p.Internal.Build.BinDir == "" && cfg.ModulesEnabled {
1702                         p.Internal.Build.BinDir = modload.BinDir()
1703                 }
1704                 if p.Internal.Build.BinDir != "" {
1705                         // Install to GOBIN or bin of GOPATH entry.
1706                         p.Target = filepath.Join(p.Internal.Build.BinDir, elem)
1707                         if !p.Goroot && strings.Contains(elem, "/") && cfg.GOBIN != "" {
1708                                 // Do not create $GOBIN/goos_goarch/elem.
1709                                 p.Target = ""
1710                                 p.Internal.GobinSubdir = true
1711                         }
1712                 }
1713                 if InstallTargetDir(p) == ToTool {
1714                         // This is for 'go tool'.
1715                         // Override all the usual logic and force it into the tool directory.
1716                         if cfg.BuildToolchainName == "gccgo" {
1717                                 p.Target = filepath.Join(base.ToolDir, elem)
1718                         } else {
1719                                 p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full)
1720                         }
1721                 }
1722                 if p.Target != "" && cfg.BuildContext.GOOS == "windows" {
1723                         p.Target += ".exe"
1724                 }
1725         } else if p.Internal.Local {
1726                 // Local import turned into absolute path.
1727                 // No permanent install target.
1728                 p.Target = ""
1729         } else {
1730                 p.Target = p.Internal.Build.PkgObj
1731                 if cfg.BuildLinkshared && p.Target != "" {
1732                         // TODO(bcmills): The reliance on p.Target implies that -linkshared does
1733                         // not work for any package that lacks a Target — such as a non-main
1734                         // package in module mode. We should probably fix that.
1735                         shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname"
1736                         shlib, err := os.ReadFile(shlibnamefile)
1737                         if err != nil && !os.IsNotExist(err) {
1738                                 base.Fatalf("reading shlibname: %v", err)
1739                         }
1740                         if err == nil {
1741                                 libname := strings.TrimSpace(string(shlib))
1742                                 if cfg.BuildContext.Compiler == "gccgo" {
1743                                         p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname)
1744                                 } else {
1745                                         p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname)
1746                                 }
1747                         }
1748                 }
1749         }
1750
1751         // Build augmented import list to add implicit dependencies.
1752         // Be careful not to add imports twice, just to avoid confusion.
1753         importPaths := p.Imports
1754         addImport := func(path string, forCompiler bool) {
1755                 for _, p := range importPaths {
1756                         if path == p {
1757                                 return
1758                         }
1759                 }
1760                 importPaths = append(importPaths, path)
1761                 if forCompiler {
1762                         p.Internal.CompiledImports = append(p.Internal.CompiledImports, path)
1763                 }
1764         }
1765
1766         // Cgo translation adds imports of "unsafe", "runtime/cgo" and "syscall",
1767         // except for certain packages, to avoid circular dependencies.
1768         if p.UsesCgo() {
1769                 addImport("unsafe", true)
1770         }
1771         if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" {
1772                 addImport("runtime/cgo", true)
1773         }
1774         if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
1775                 addImport("syscall", true)
1776         }
1777
1778         // SWIG adds imports of some standard packages.
1779         if p.UsesSwig() {
1780                 addImport("unsafe", true)
1781                 if cfg.BuildContext.Compiler != "gccgo" {
1782                         addImport("runtime/cgo", true)
1783                 }
1784                 addImport("syscall", true)
1785                 addImport("sync", true)
1786
1787                 // TODO: The .swig and .swigcxx files can use
1788                 // %go_import directives to import other packages.
1789         }
1790
1791         // The linker loads implicit dependencies.
1792         if p.Name == "main" && !p.Internal.ForceLibrary {
1793                 for _, dep := range LinkerDeps(p) {
1794                         addImport(dep, false)
1795                 }
1796         }
1797
1798         // Check for case-insensitive collisions of import paths.
1799         fold := str.ToFold(p.ImportPath)
1800         if other := foldPath[fold]; other == "" {
1801                 foldPath[fold] = p.ImportPath
1802         } else if other != p.ImportPath {
1803                 setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other))
1804                 return
1805         }
1806
1807         if !SafeArg(p.ImportPath) {
1808                 setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath))
1809                 return
1810         }
1811
1812         // Errors after this point are caused by this package, not the importing
1813         // package. Pushing the path here prevents us from reporting the error
1814         // with the position of the import declaration.
1815         stk.Push(path)
1816         defer stk.Pop()
1817
1818         p.EmbedFiles, p.Internal.Embed, err = resolveEmbed(p.Dir, p.EmbedPatterns)
1819         if err != nil {
1820                 p.Incomplete = true
1821                 setError(err)
1822                 embedErr := err.(*EmbedError)
1823                 p.Error.setPos(p.Internal.Build.EmbedPatternPos[embedErr.Pattern])
1824         }
1825
1826         // Check for case-insensitive collision of input files.
1827         // To avoid problems on case-insensitive files, we reject any package
1828         // where two different input files have equal names under a case-insensitive
1829         // comparison.
1830         inputs := p.AllFiles()
1831         f1, f2 := str.FoldDup(inputs)
1832         if f1 != "" {
1833                 setError(fmt.Errorf("case-insensitive file name collision: %q and %q", f1, f2))
1834                 return
1835         }
1836
1837         // If first letter of input file is ASCII, it must be alphanumeric.
1838         // This avoids files turning into flags when invoking commands,
1839         // and other problems we haven't thought of yet.
1840         // Also, _cgo_ files must be generated by us, not supplied.
1841         // They are allowed to have //go:cgo_ldflag directives.
1842         // The directory scan ignores files beginning with _,
1843         // so we shouldn't see any _cgo_ files anyway, but just be safe.
1844         for _, file := range inputs {
1845                 if !SafeArg(file) || strings.HasPrefix(file, "_cgo_") {
1846                         setError(fmt.Errorf("invalid input file name %q", file))
1847                         return
1848                 }
1849         }
1850         if name := pathpkg.Base(p.ImportPath); !SafeArg(name) {
1851                 setError(fmt.Errorf("invalid input directory name %q", name))
1852                 return
1853         }
1854
1855         // Build list of imported packages and full dependency list.
1856         imports := make([]*Package, 0, len(p.Imports))
1857         for i, path := range importPaths {
1858                 if path == "C" {
1859                         continue
1860                 }
1861                 p1 := LoadImport(ctx, path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport)
1862
1863                 path = p1.ImportPath
1864                 importPaths[i] = path
1865                 if i < len(p.Imports) {
1866                         p.Imports[i] = path
1867                 }
1868
1869                 imports = append(imports, p1)
1870                 if p1.Incomplete {
1871                         p.Incomplete = true
1872                 }
1873         }
1874         p.Internal.Imports = imports
1875         p.collectDeps()
1876
1877         // unsafe is a fake package.
1878         if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") {
1879                 p.Target = ""
1880         }
1881
1882         // If cgo is not enabled, ignore cgo supporting sources
1883         // just as we ignore go files containing import "C".
1884         if !cfg.BuildContext.CgoEnabled {
1885                 p.CFiles = nil
1886                 p.CXXFiles = nil
1887                 p.MFiles = nil
1888                 p.SwigFiles = nil
1889                 p.SwigCXXFiles = nil
1890                 // Note that SFiles are okay (they go to the Go assembler)
1891                 // and HFiles are okay (they might be used by the SFiles).
1892                 // Also Sysofiles are okay (they might not contain object
1893                 // code; see issue #16050).
1894         }
1895
1896         // The gc toolchain only permits C source files with cgo or SWIG.
1897         if len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == "gc" {
1898                 setError(fmt.Errorf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " ")))
1899                 return
1900         }
1901
1902         // C++, Objective-C, and Fortran source files are permitted only with cgo or SWIG,
1903         // regardless of toolchain.
1904         if len(p.CXXFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
1905                 setError(fmt.Errorf("C++ source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CXXFiles, " ")))
1906                 return
1907         }
1908         if len(p.MFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
1909                 setError(fmt.Errorf("Objective-C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.MFiles, " ")))
1910                 return
1911         }
1912         if len(p.FFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
1913                 setError(fmt.Errorf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " ")))
1914                 return
1915         }
1916
1917         if cfg.ModulesEnabled && p.Error == nil {
1918                 mainPath := p.ImportPath
1919                 if p.Internal.CmdlineFiles {
1920                         mainPath = "command-line-arguments"
1921                 }
1922                 p.Module = modload.PackageModuleInfo(mainPath)
1923                 if p.Name == "main" && len(p.DepsErrors) == 0 {
1924                         p.Internal.BuildInfo = modload.PackageBuildInfo(mainPath, p.Deps)
1925                 }
1926         }
1927 }
1928
1929 // An EmbedError indicates a problem with a go:embed directive.
1930 type EmbedError struct {
1931         Pattern string
1932         Err     error
1933 }
1934
1935 func (e *EmbedError) Error() string {
1936         return fmt.Sprintf("pattern %s: %v", e.Pattern, e.Err)
1937 }
1938
1939 func (e *EmbedError) Unwrap() error {
1940         return e.Err
1941 }
1942
1943 // ResolveEmbed resolves //go:embed patterns and returns only the file list.
1944 // For use by go mod vendor to find embedded files it should copy into the
1945 // vendor directory.
1946 // TODO(#42504): Once go mod vendor uses load.PackagesAndErrors, just
1947 // call (*Package).ResolveEmbed
1948 func ResolveEmbed(dir string, patterns []string) ([]string, error) {
1949         files, _, err := resolveEmbed(dir, patterns)
1950         return files, err
1951 }
1952
1953 // resolveEmbed resolves //go:embed patterns to precise file lists.
1954 // It sets files to the list of unique files matched (for go list),
1955 // and it sets pmap to the more precise mapping from
1956 // patterns to files.
1957 func resolveEmbed(pkgdir string, patterns []string) (files []string, pmap map[string][]string, err error) {
1958         var pattern string
1959         defer func() {
1960                 if err != nil {
1961                         err = &EmbedError{
1962                                 Pattern: pattern,
1963                                 Err:     err,
1964                         }
1965                 }
1966         }()
1967
1968         // TODO(rsc): All these messages need position information for better error reports.
1969         pmap = make(map[string][]string)
1970         have := make(map[string]int)
1971         dirOK := make(map[string]bool)
1972         pid := 0 // pattern ID, to allow reuse of have map
1973         for _, pattern = range patterns {
1974                 pid++
1975
1976                 // Check pattern is valid for //go:embed.
1977                 if _, err := path.Match(pattern, ""); err != nil || !validEmbedPattern(pattern) {
1978                         return nil, nil, fmt.Errorf("invalid pattern syntax")
1979                 }
1980
1981                 // Glob to find matches.
1982                 match, err := fsys.Glob(pkgdir + string(filepath.Separator) + filepath.FromSlash(pattern))
1983                 if err != nil {
1984                         return nil, nil, err
1985                 }
1986
1987                 // Filter list of matches down to the ones that will still exist when
1988                 // the directory is packaged up as a module. (If p.Dir is in the module cache,
1989                 // only those files exist already, but if p.Dir is in the current module,
1990                 // then there may be other things lying around, like symbolic links or .git directories.)
1991                 var list []string
1992                 for _, file := range match {
1993                         rel := filepath.ToSlash(file[len(pkgdir)+1:]) // file, relative to p.Dir
1994
1995                         what := "file"
1996                         info, err := fsys.Lstat(file)
1997                         if err != nil {
1998                                 return nil, nil, err
1999                         }
2000                         if info.IsDir() {
2001                                 what = "directory"
2002                         }
2003
2004                         // Check that directories along path do not begin a new module
2005                         // (do not contain a go.mod).
2006                         for dir := file; len(dir) > len(pkgdir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) {
2007                                 if _, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil {
2008                                         return nil, nil, fmt.Errorf("cannot embed %s %s: in different module", what, rel)
2009                                 }
2010                                 if dir != file {
2011                                         if info, err := fsys.Lstat(dir); err == nil && !info.IsDir() {
2012                                                 return nil, nil, fmt.Errorf("cannot embed %s %s: in non-directory %s", what, rel, dir[len(pkgdir)+1:])
2013                                         }
2014                                 }
2015                                 dirOK[dir] = true
2016                                 if elem := filepath.Base(dir); isBadEmbedName(elem) {
2017                                         if dir == file {
2018                                                 return nil, nil, fmt.Errorf("cannot embed %s %s: invalid name %s", what, rel, elem)
2019                                         } else {
2020                                                 return nil, nil, fmt.Errorf("cannot embed %s %s: in invalid directory %s", what, rel, elem)
2021                                         }
2022                                 }
2023                         }
2024
2025                         switch {
2026                         default:
2027                                 return nil, nil, fmt.Errorf("cannot embed irregular file %s", rel)
2028
2029                         case info.Mode().IsRegular():
2030                                 if have[rel] != pid {
2031                                         have[rel] = pid
2032                                         list = append(list, rel)
2033                                 }
2034
2035                         case info.IsDir():
2036                                 // Gather all files in the named directory, stopping at module boundaries
2037                                 // and ignoring files that wouldn't be packaged into a module.
2038                                 count := 0
2039                                 err := fsys.Walk(file, func(path string, info os.FileInfo, err error) error {
2040                                         if err != nil {
2041                                                 return err
2042                                         }
2043                                         rel := filepath.ToSlash(path[len(pkgdir)+1:])
2044                                         name := info.Name()
2045                                         if path != file && (isBadEmbedName(name) || name[0] == '.' || name[0] == '_') {
2046                                                 // Ignore bad names, assuming they won't go into modules.
2047                                                 // Also avoid hidden files that user may not know about.
2048                                                 // See golang.org/issue/42328.
2049                                                 if info.IsDir() {
2050                                                         return fs.SkipDir
2051                                                 }
2052                                                 return nil
2053                                         }
2054                                         if info.IsDir() {
2055                                                 if _, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil {
2056                                                         return filepath.SkipDir
2057                                                 }
2058                                                 return nil
2059                                         }
2060                                         if !info.Mode().IsRegular() {
2061                                                 return nil
2062                                         }
2063                                         count++
2064                                         if have[rel] != pid {
2065                                                 have[rel] = pid
2066                                                 list = append(list, rel)
2067                                         }
2068                                         return nil
2069                                 })
2070                                 if err != nil {
2071                                         return nil, nil, err
2072                                 }
2073                                 if count == 0 {
2074                                         return nil, nil, fmt.Errorf("cannot embed directory %s: contains no embeddable files", rel)
2075                                 }
2076                         }
2077                 }
2078
2079                 if len(list) == 0 {
2080                         return nil, nil, fmt.Errorf("no matching files found")
2081                 }
2082                 sort.Strings(list)
2083                 pmap[pattern] = list
2084         }
2085
2086         for file := range have {
2087                 files = append(files, file)
2088         }
2089         sort.Strings(files)
2090         return files, pmap, nil
2091 }
2092
2093 func validEmbedPattern(pattern string) bool {
2094         return pattern != "." && fs.ValidPath(pattern)
2095 }
2096
2097 // isBadEmbedName reports whether name is the base name of a file that
2098 // can't or won't be included in modules and therefore shouldn't be treated
2099 // as existing for embedding.
2100 func isBadEmbedName(name string) bool {
2101         if err := module.CheckFilePath(name); err != nil {
2102                 return true
2103         }
2104         switch name {
2105         // Empty string should be impossible but make it bad.
2106         case "":
2107                 return true
2108         // Version control directories won't be present in module.
2109         case ".bzr", ".hg", ".git", ".svn":
2110                 return true
2111         }
2112         return false
2113 }
2114
2115 // collectDeps populates p.Deps and p.DepsErrors by iterating over
2116 // p.Internal.Imports.
2117 //
2118 // TODO(jayconrod): collectDeps iterates over transitive imports for every
2119 // package. We should only need to visit direct imports.
2120 func (p *Package) collectDeps() {
2121         deps := make(map[string]*Package)
2122         var q []*Package
2123         q = append(q, p.Internal.Imports...)
2124         for i := 0; i < len(q); i++ {
2125                 p1 := q[i]
2126                 path := p1.ImportPath
2127                 // The same import path could produce an error or not,
2128                 // depending on what tries to import it.
2129                 // Prefer to record entries with errors, so we can report them.
2130                 p0 := deps[path]
2131                 if p0 == nil || p1.Error != nil && (p0.Error == nil || len(p0.Error.ImportStack) > len(p1.Error.ImportStack)) {
2132                         deps[path] = p1
2133                         for _, p2 := range p1.Internal.Imports {
2134                                 if deps[p2.ImportPath] != p2 {
2135                                         q = append(q, p2)
2136                                 }
2137                         }
2138                 }
2139         }
2140
2141         p.Deps = make([]string, 0, len(deps))
2142         for dep := range deps {
2143                 p.Deps = append(p.Deps, dep)
2144         }
2145         sort.Strings(p.Deps)
2146         for _, dep := range p.Deps {
2147                 p1 := deps[dep]
2148                 if p1 == nil {
2149                         panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath)
2150                 }
2151                 if p1.Error != nil {
2152                         p.DepsErrors = append(p.DepsErrors, p1.Error)
2153                 }
2154         }
2155 }
2156
2157 // SafeArg reports whether arg is a "safe" command-line argument,
2158 // meaning that when it appears in a command-line, it probably
2159 // doesn't have some special meaning other than its own name.
2160 // Obviously args beginning with - are not safe (they look like flags).
2161 // Less obviously, args beginning with @ are not safe (they look like
2162 // GNU binutils flagfile specifiers, sometimes called "response files").
2163 // To be conservative, we reject almost any arg beginning with non-alphanumeric ASCII.
2164 // We accept leading . _ and / as likely in file system paths.
2165 // There is a copy of this function in cmd/compile/internal/gc/noder.go.
2166 func SafeArg(name string) bool {
2167         if name == "" {
2168                 return false
2169         }
2170         c := name[0]
2171         return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
2172 }
2173
2174 // LinkerDeps returns the list of linker-induced dependencies for main package p.
2175 func LinkerDeps(p *Package) []string {
2176         // Everything links runtime.
2177         deps := []string{"runtime"}
2178
2179         // External linking mode forces an import of runtime/cgo.
2180         if externalLinkingForced(p) && cfg.BuildContext.Compiler != "gccgo" {
2181                 deps = append(deps, "runtime/cgo")
2182         }
2183         // On ARM with GOARM=5, it forces an import of math, for soft floating point.
2184         if cfg.Goarch == "arm" {
2185                 deps = append(deps, "math")
2186         }
2187         // Using the race detector forces an import of runtime/race.
2188         if cfg.BuildRace {
2189                 deps = append(deps, "runtime/race")
2190         }
2191         // Using memory sanitizer forces an import of runtime/msan.
2192         if cfg.BuildMSan {
2193                 deps = append(deps, "runtime/msan")
2194         }
2195
2196         return deps
2197 }
2198
2199 // externalLinkingForced reports whether external linking is being
2200 // forced even for programs that do not use cgo.
2201 func externalLinkingForced(p *Package) bool {
2202         if !cfg.BuildContext.CgoEnabled {
2203                 return false
2204         }
2205
2206         // Some targets must use external linking even inside GOROOT.
2207         switch cfg.BuildContext.GOOS {
2208         case "android":
2209                 if cfg.BuildContext.GOARCH != "arm64" {
2210                         return true
2211                 }
2212         case "ios":
2213                 return true
2214         }
2215
2216         // Currently build modes c-shared, pie (on systems that do not
2217         // support PIE with internal linking mode (currently all
2218         // systems: issue #18968)), plugin, and -linkshared force
2219         // external linking mode, as of course does
2220         // -ldflags=-linkmode=external. External linking mode forces
2221         // an import of runtime/cgo.
2222         // If there are multiple -linkmode options, the last one wins.
2223         pieCgo := cfg.BuildBuildmode == "pie" && !sys.InternalLinkPIESupported(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH)
2224         linkmodeExternal := false
2225         if p != nil {
2226                 ldflags := BuildLdflags.For(p)
2227                 for i := len(ldflags) - 1; i >= 0; i-- {
2228                         a := ldflags[i]
2229                         if a == "-linkmode=external" ||
2230                                 a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" {
2231                                 linkmodeExternal = true
2232                                 break
2233                         } else if a == "-linkmode=internal" ||
2234                                 a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "internal" {
2235                                 break
2236                         }
2237                 }
2238         }
2239
2240         return cfg.BuildBuildmode == "c-shared" || cfg.BuildBuildmode == "plugin" || pieCgo || cfg.BuildLinkshared || linkmodeExternal
2241 }
2242
2243 // mkAbs rewrites list, which must be paths relative to p.Dir,
2244 // into a sorted list of absolute paths. It edits list in place but for
2245 // convenience also returns list back to its caller.
2246 func (p *Package) mkAbs(list []string) []string {
2247         for i, f := range list {
2248                 list[i] = filepath.Join(p.Dir, f)
2249         }
2250         sort.Strings(list)
2251         return list
2252 }
2253
2254 // InternalGoFiles returns the list of Go files being built for the package,
2255 // using absolute paths.
2256 func (p *Package) InternalGoFiles() []string {
2257         return p.mkAbs(str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles))
2258 }
2259
2260 // InternalXGoFiles returns the list of Go files being built for the XTest package,
2261 // using absolute paths.
2262 func (p *Package) InternalXGoFiles() []string {
2263         return p.mkAbs(p.XTestGoFiles)
2264 }
2265
2266 // InternalGoFiles returns the list of all Go files possibly relevant for the package,
2267 // using absolute paths. "Possibly relevant" means that files are not excluded
2268 // due to build tags, but files with names beginning with . or _ are still excluded.
2269 func (p *Package) InternalAllGoFiles() []string {
2270         return p.mkAbs(str.StringList(p.IgnoredGoFiles, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles))
2271 }
2272
2273 // usesSwig reports whether the package needs to run SWIG.
2274 func (p *Package) UsesSwig() bool {
2275         return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0
2276 }
2277
2278 // usesCgo reports whether the package needs to run cgo
2279 func (p *Package) UsesCgo() bool {
2280         return len(p.CgoFiles) > 0
2281 }
2282
2283 // PackageList returns the list of packages in the dag rooted at roots
2284 // as visited in a depth-first post-order traversal.
2285 func PackageList(roots []*Package) []*Package {
2286         seen := map[*Package]bool{}
2287         all := []*Package{}
2288         var walk func(*Package)
2289         walk = func(p *Package) {
2290                 if seen[p] {
2291                         return
2292                 }
2293                 seen[p] = true
2294                 for _, p1 := range p.Internal.Imports {
2295                         walk(p1)
2296                 }
2297                 all = append(all, p)
2298         }
2299         for _, root := range roots {
2300                 walk(root)
2301         }
2302         return all
2303 }
2304
2305 // TestPackageList returns the list of packages in the dag rooted at roots
2306 // as visited in a depth-first post-order traversal, including the test
2307 // imports of the roots. This ignores errors in test packages.
2308 func TestPackageList(ctx context.Context, roots []*Package) []*Package {
2309         seen := map[*Package]bool{}
2310         all := []*Package{}
2311         var walk func(*Package)
2312         walk = func(p *Package) {
2313                 if seen[p] {
2314                         return
2315                 }
2316                 seen[p] = true
2317                 for _, p1 := range p.Internal.Imports {
2318                         walk(p1)
2319                 }
2320                 all = append(all, p)
2321         }
2322         walkTest := func(root *Package, path string) {
2323                 var stk ImportStack
2324                 p1 := LoadImport(ctx, path, root.Dir, root, &stk, root.Internal.Build.TestImportPos[path], ResolveImport)
2325                 if p1.Error == nil {
2326                         walk(p1)
2327                 }
2328         }
2329         for _, root := range roots {
2330                 walk(root)
2331                 for _, path := range root.TestImports {
2332                         walkTest(root, path)
2333                 }
2334                 for _, path := range root.XTestImports {
2335                         walkTest(root, path)
2336                 }
2337         }
2338         return all
2339 }
2340
2341 // LoadImportWithFlags loads the package with the given import path and
2342 // sets tool flags on that package. This function is useful loading implicit
2343 // dependencies (like sync/atomic for coverage).
2344 // TODO(jayconrod): delete this function and set flags automatically
2345 // in LoadImport instead.
2346 func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
2347         p := LoadImport(context.TODO(), path, srcDir, parent, stk, importPos, mode)
2348         setToolFlags(p)
2349         return p
2350 }
2351
2352 // ModResolveTests indicates whether calls to the module loader should also
2353 // resolve test dependencies of the requested packages.
2354 //
2355 // If ModResolveTests is true, then the module loader needs to resolve test
2356 // dependencies at the same time as packages; otherwise, the test dependencies
2357 // of those packages could be missing, and resolving those missing dependencies
2358 // could change the selected versions of modules that provide other packages.
2359 //
2360 // TODO(#40775): Change this from a global variable to an explicit function
2361 // argument where needed.
2362 var ModResolveTests bool
2363
2364 // PackagesAndErrors returns the packages named by the command line arguments
2365 // 'patterns'. If a named package cannot be loaded, PackagesAndErrors returns
2366 // a *Package with the Error field describing the failure. If errors are found
2367 // loading imported packages, the DepsErrors field is set. The Incomplete field
2368 // may be set as well.
2369 //
2370 // To obtain a flat list of packages, use PackageList.
2371 // To report errors loading packages, use ReportPackageErrors.
2372 func PackagesAndErrors(ctx context.Context, patterns []string) []*Package {
2373         ctx, span := trace.StartSpan(ctx, "load.PackagesAndErrors")
2374         defer span.Done()
2375
2376         for _, p := range patterns {
2377                 // Listing is only supported with all patterns referring to either:
2378                 // - Files that are part of the same directory.
2379                 // - Explicit package paths or patterns.
2380                 if strings.HasSuffix(p, ".go") {
2381                         // We need to test whether the path is an actual Go file and not a
2382                         // package path or pattern ending in '.go' (see golang.org/issue/34653).
2383                         if fi, err := fsys.Stat(p); err == nil && !fi.IsDir() {
2384                                 return []*Package{GoFilesPackage(ctx, patterns)}
2385                         }
2386                 }
2387         }
2388
2389         var matches []*search.Match
2390         if modload.Init(); cfg.ModulesEnabled {
2391                 loadOpts := modload.PackageOpts{
2392                         ResolveMissingImports: true,
2393                         LoadTests:             ModResolveTests,
2394                         SilenceErrors:         true,
2395                 }
2396                 matches, _ = modload.LoadPackages(ctx, loadOpts, patterns...)
2397         } else {
2398                 matches = search.ImportPaths(patterns)
2399         }
2400
2401         var (
2402                 pkgs    []*Package
2403                 stk     ImportStack
2404                 seenPkg = make(map[*Package]bool)
2405         )
2406
2407         pre := newPreload()
2408         defer pre.flush()
2409         pre.preloadMatches(matches)
2410
2411         for _, m := range matches {
2412                 for _, pkg := range m.Pkgs {
2413                         if pkg == "" {
2414                                 panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern()))
2415                         }
2416                         p := loadImport(ctx, pre, pkg, base.Cwd, nil, &stk, nil, 0)
2417                         p.Match = append(p.Match, m.Pattern())
2418                         p.Internal.CmdlinePkg = true
2419                         if m.IsLiteral() {
2420                                 // Note: do not set = m.IsLiteral unconditionally
2421                                 // because maybe we'll see p matching both
2422                                 // a literal and also a non-literal pattern.
2423                                 p.Internal.CmdlinePkgLiteral = true
2424                         }
2425                         if seenPkg[p] {
2426                                 continue
2427                         }
2428                         seenPkg[p] = true
2429                         pkgs = append(pkgs, p)
2430                 }
2431
2432                 if len(m.Errs) > 0 {
2433                         // In addition to any packages that were actually resolved from the
2434                         // pattern, there was some error in resolving the pattern itself.
2435                         // Report it as a synthetic package.
2436                         p := new(Package)
2437                         p.ImportPath = m.Pattern()
2438                         // Pass an empty ImportStack and nil importPos: the error arose from a pattern, not an import.
2439                         var stk ImportStack
2440                         var importPos []token.Position
2441                         p.setLoadPackageDataError(m.Errs[0], m.Pattern(), &stk, importPos)
2442                         p.Incomplete = true
2443                         p.Match = append(p.Match, m.Pattern())
2444                         p.Internal.CmdlinePkg = true
2445                         if m.IsLiteral() {
2446                                 p.Internal.CmdlinePkgLiteral = true
2447                         }
2448                         pkgs = append(pkgs, p)
2449                 }
2450         }
2451
2452         // Now that CmdlinePkg is set correctly,
2453         // compute the effective flags for all loaded packages
2454         // (not just the ones matching the patterns but also
2455         // their dependencies).
2456         setToolFlags(pkgs...)
2457
2458         return pkgs
2459 }
2460
2461 // CheckPackageErrors prints errors encountered loading pkgs and their
2462 // dependencies, then exits with a non-zero status if any errors were found.
2463 func CheckPackageErrors(pkgs []*Package) {
2464         printed := map[*PackageError]bool{}
2465         for _, pkg := range pkgs {
2466                 if pkg.Error != nil {
2467                         base.Errorf("%v", pkg.Error)
2468                         printed[pkg.Error] = true
2469                 }
2470                 for _, err := range pkg.DepsErrors {
2471                         // Since these are errors in dependencies,
2472                         // the same error might show up multiple times,
2473                         // once in each package that depends on it.
2474                         // Only print each once.
2475                         if !printed[err] {
2476                                 printed[err] = true
2477                                 base.Errorf("%v", err)
2478                         }
2479                 }
2480         }
2481         base.ExitIfErrors()
2482
2483         // Check for duplicate loads of the same package.
2484         // That should be impossible, but if it does happen then
2485         // we end up trying to build the same package twice,
2486         // usually in parallel overwriting the same files,
2487         // which doesn't work very well.
2488         seen := map[string]bool{}
2489         reported := map[string]bool{}
2490         for _, pkg := range PackageList(pkgs) {
2491                 if seen[pkg.ImportPath] && !reported[pkg.ImportPath] {
2492                         reported[pkg.ImportPath] = true
2493                         base.Errorf("internal error: duplicate loads of %s", pkg.ImportPath)
2494                 }
2495                 seen[pkg.ImportPath] = true
2496         }
2497         base.ExitIfErrors()
2498 }
2499
2500 func setToolFlags(pkgs ...*Package) {
2501         for _, p := range PackageList(pkgs) {
2502                 p.Internal.Asmflags = BuildAsmflags.For(p)
2503                 p.Internal.Gcflags = BuildGcflags.For(p)
2504                 p.Internal.Ldflags = BuildLdflags.For(p)
2505                 p.Internal.Gccgoflags = BuildGccgoflags.For(p)
2506         }
2507 }
2508
2509 // GoFilesPackage creates a package for building a collection of Go files
2510 // (typically named on the command line). The target is named p.a for
2511 // package p or named after the first Go file for package main.
2512 func GoFilesPackage(ctx context.Context, gofiles []string) *Package {
2513         modload.Init()
2514
2515         for _, f := range gofiles {
2516                 if !strings.HasSuffix(f, ".go") {
2517                         pkg := new(Package)
2518                         pkg.Internal.Local = true
2519                         pkg.Internal.CmdlineFiles = true
2520                         pkg.Name = f
2521                         pkg.Error = &PackageError{
2522                                 Err: fmt.Errorf("named files must be .go files: %s", pkg.Name),
2523                         }
2524                         return pkg
2525                 }
2526         }
2527
2528         var stk ImportStack
2529         ctxt := cfg.BuildContext
2530         ctxt.UseAllFiles = true
2531
2532         // Synthesize fake "directory" that only shows the named files,
2533         // to make it look like this is a standard package or
2534         // command directory. So that local imports resolve
2535         // consistently, the files must all be in the same directory.
2536         var dirent []fs.FileInfo
2537         var dir string
2538         for _, file := range gofiles {
2539                 fi, err := fsys.Stat(file)
2540                 if err != nil {
2541                         base.Fatalf("%s", err)
2542                 }
2543                 if fi.IsDir() {
2544                         base.Fatalf("%s is a directory, should be a Go file", file)
2545                 }
2546                 dir1, _ := filepath.Split(file)
2547                 if dir1 == "" {
2548                         dir1 = "./"
2549                 }
2550                 if dir == "" {
2551                         dir = dir1
2552                 } else if dir != dir1 {
2553                         base.Fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
2554                 }
2555                 dirent = append(dirent, fi)
2556         }
2557         ctxt.ReadDir = func(string) ([]fs.FileInfo, error) { return dirent, nil }
2558
2559         if cfg.ModulesEnabled {
2560                 modload.ImportFromFiles(ctx, gofiles)
2561         }
2562
2563         var err error
2564         if dir == "" {
2565                 dir = base.Cwd
2566         }
2567         dir, err = filepath.Abs(dir)
2568         if err != nil {
2569                 base.Fatalf("%s", err)
2570         }
2571
2572         bp, err := ctxt.ImportDir(dir, 0)
2573         pkg := new(Package)
2574         pkg.Internal.Local = true
2575         pkg.Internal.CmdlineFiles = true
2576         pkg.load(ctx, "command-line-arguments", &stk, nil, bp, err)
2577         pkg.Internal.LocalPrefix = dirToImportPath(dir)
2578         pkg.ImportPath = "command-line-arguments"
2579         pkg.Target = ""
2580         pkg.Match = gofiles
2581
2582         if pkg.Name == "main" {
2583                 exe := pkg.DefaultExecName() + cfg.ExeSuffix
2584
2585                 if cfg.GOBIN != "" {
2586                         pkg.Target = filepath.Join(cfg.GOBIN, exe)
2587                 } else if cfg.ModulesEnabled {
2588                         pkg.Target = filepath.Join(modload.BinDir(), exe)
2589                 }
2590         }
2591
2592         setToolFlags(pkg)
2593
2594         return pkg
2595 }