1// Copyright 2011 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.45// Package load loads packages.6package load78import (9 "bytes"10 "context"11 "encoding/json"12 "errors"13 "fmt"14 "go/build"15 "go/scanner"16 "go/token"17 "internal/godebug"18 "internal/platform"19 "io/fs"20 "os"21 pathpkg "path"22 "path/filepath"23 "runtime"24 "runtime/debug"25 "slices"26 "sort"27 "strconv"28 "strings"29 "time"30 "unicode"31 "unicode/utf8"3233 "cmd/internal/objabi"3435 "cmd/go/internal/base"36 "cmd/go/internal/cfg"37 "cmd/go/internal/fips140"38 "cmd/go/internal/fsys"39 "cmd/go/internal/gover"40 "cmd/go/internal/imports"41 "cmd/go/internal/modfetch"42 "cmd/go/internal/modindex"43 "cmd/go/internal/modinfo"44 "cmd/go/internal/modload"45 "cmd/go/internal/search"46 "cmd/go/internal/str"47 "cmd/go/internal/trace"48 "cmd/go/internal/vcs"49 "cmd/internal/par"50 "cmd/internal/pathcache"51 "cmd/internal/pkgpattern"5253 "golang.org/x/mod/modfile"54 "golang.org/x/mod/module"55)5657// A Package describes a single package found in a directory.58type Package struct {59 PackagePublic // visible in 'go list'60 Internal PackageInternal // for use inside go command only61}6263type PackagePublic struct {64 // Note: These fields are part of the go command's public API.65 // See list.go. It is okay to add fields, but not to change or66 // remove existing ones. Keep in sync with ../list/list.go67 Dir string `json:",omitempty"` // directory containing package sources68 ImportPath string `json:",omitempty"` // import path of package in dir69 ImportComment string `json:",omitempty"` // path in import comment on package statement70 Name string `json:",omitempty"` // package name71 Doc string `json:",omitempty"` // package documentation string72 Target string `json:",omitempty"` // installed target for this package (may be executable)73 Shlib string `json:",omitempty"` // the shared library that contains this package (only set when -linkshared)74 Root string `json:",omitempty"` // Go root, Go path dir, or module root dir containing this package75 ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory76 ForTest string `json:",omitempty"` // package is only for use in named test77 Export string `json:",omitempty"` // file containing export data (set by go list -export)78 BuildID string `json:",omitempty"` // build ID of the compiled package (set by go list -export)79 Module *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any80 Match []string `json:",omitempty"` // command-line patterns matching this package81 Goroot bool `json:",omitempty"` // is this package found in the Go root?82 Standard bool `json:",omitempty"` // is this package part of the standard Go library?83 DepOnly bool `json:",omitempty"` // package is only as a dependency, not explicitly listed84 BinaryOnly bool `json:",omitempty"` // package cannot be recompiled85 Incomplete bool `json:",omitempty"` // was there an error loading this package or dependencies?8687 DefaultGODEBUG string `json:",omitempty"` // default GODEBUG setting (only for Name=="main")8889 // Stale and StaleReason remain here *only* for the list command.90 // They are only initialized in preparation for list execution.91 // The regular build determines staleness on the fly during action execution.92 Stale bool `json:",omitempty"` // would 'go install' do anything for this package?93 StaleReason string `json:",omitempty"` // why is Stale true?9495 // Source files96 // If you add to this list you MUST add to p.AllFiles (below) too.97 // Otherwise file name security lists will not apply to any new additions.98 GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)99 CgoFiles []string `json:",omitempty"` // .go source files that import "C"100 CompiledGoFiles []string `json:",omitempty"` // .go output from running cgo on CgoFiles101 IgnoredGoFiles []string `json:",omitempty"` // .go source files ignored due to build constraints102 InvalidGoFiles []string `json:",omitempty"` // .go source files with detected problems (parse error, wrong package name, and so on)103 IgnoredOtherFiles []string `json:",omitempty"` // non-.go source files ignored due to build constraints104 CFiles []string `json:",omitempty"` // .c source files105 CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files106 MFiles []string `json:",omitempty"` // .m source files107 HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files108 FFiles []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files109 SFiles []string `json:",omitempty"` // .s source files110 SwigFiles []string `json:",omitempty"` // .swig files111 SwigCXXFiles []string `json:",omitempty"` // .swigcxx files112 SysoFiles []string `json:",omitempty"` // .syso system object files added to package113114 // Embedded files115 EmbedPatterns []string `json:",omitempty"` // //go:embed patterns116 EmbedFiles []string `json:",omitempty"` // files matched by EmbedPatterns117118 // Cgo directives119 CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler120 CgoCPPFLAGS []string `json:",omitempty"` // cgo: flags for C preprocessor121 CgoCXXFLAGS []string `json:",omitempty"` // cgo: flags for C++ compiler122 CgoFFLAGS []string `json:",omitempty"` // cgo: flags for Fortran compiler123 CgoLDFLAGS []string `json:",omitempty"` // cgo: flags for linker124 CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names125126 // Dependency information127 Imports []string `json:",omitempty"` // import paths used by this package128 ImportMap map[string]string `json:",omitempty"` // map from source import to ImportPath (identity entries omitted)129 Deps []string `json:",omitempty"` // all (recursively) imported dependencies130131 // Error information132 // Incomplete is above, packed into the other bools133 Error *PackageError `json:",omitempty"` // error loading this package (not dependencies)134 DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies, collected by go list before output135136 // Test information137 // If you add to this list you MUST add to p.AllFiles (below) too.138 // Otherwise file name security lists will not apply to any new additions.139 TestGoFiles []string `json:",omitempty"` // _test.go files in package140 TestImports []string `json:",omitempty"` // imports from TestGoFiles141 TestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns142 TestEmbedFiles []string `json:",omitempty"` // files matched by TestEmbedPatterns143 XTestGoFiles []string `json:",omitempty"` // _test.go files outside package144 XTestImports []string `json:",omitempty"` // imports from XTestGoFiles145 XTestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns146 XTestEmbedFiles []string `json:",omitempty"` // files matched by XTestEmbedPatterns147}148149// AllFiles returns the names of all the files considered for the package.150// This is used for sanity and security checks, so we include all files,151// even IgnoredGoFiles, because some subcommands consider them.152// The go/build package filtered others out (like foo_wrongGOARCH.s)153// and that's OK.154func (p *Package) AllFiles() []string {155 files := str.StringList(156 p.GoFiles,157 p.CgoFiles,158 // no p.CompiledGoFiles, because they are from GoFiles or generated by us159 p.IgnoredGoFiles,160 // no p.InvalidGoFiles, because they are from GoFiles161 p.IgnoredOtherFiles,162 p.CFiles,163 p.CXXFiles,164 p.MFiles,165 p.HFiles,166 p.FFiles,167 p.SFiles,168 p.SwigFiles,169 p.SwigCXXFiles,170 p.SysoFiles,171 p.TestGoFiles,172 p.XTestGoFiles,173 )174175 // EmbedFiles may overlap with the other files.176 // Dedup, but delay building the map as long as possible.177 // Only files in the current directory (no slash in name)178 // need to be checked against the files variable above.179 var have map[string]bool180 for _, file := range p.EmbedFiles {181 if !strings.Contains(file, "/") {182 if have == nil {183 have = make(map[string]bool)184 for _, file := range files {185 have[file] = true186 }187 }188 if have[file] {189 continue190 }191 }192 files = append(files, file)193 }194 return files195}196197// Desc returns the package "description", for use in b.showOutput.198func (p *Package) Desc() string {199 if p.ForTest != "" {200 return p.ImportPath + " [" + p.ForTest + ".test]"201 }202 if p.Internal.ForMain != "" {203 return p.ImportPath + " [" + p.Internal.ForMain + "]"204 }205 return p.ImportPath206}207208// IsTestOnly reports whether p is a test-only package.209//210// A “test-only” package is one that:211// - is a test-only variant of an ordinary package, or212// - is a synthesized "main" package for a test binary, or213// - contains only _test.go files.214func (p *Package) IsTestOnly() bool {215 return p.ForTest != "" ||216 p.Internal.TestmainGo != nil ||217 len(p.TestGoFiles)+len(p.XTestGoFiles) > 0 && len(p.GoFiles)+len(p.CgoFiles) == 0218}219220type PackageInternal struct {221 // Unexported fields are not part of the public API.222 Build *build.Package223 Imports []*Package // this package's direct imports224 CompiledImports []string // additional Imports necessary when using CompiledGoFiles (all from standard library); 1:1 with the end of PackagePublic.Imports225 RawImports []string // this package's original imports as they appear in the text of the program; 1:1 with the end of PackagePublic.Imports226 ForceLibrary bool // this package is a library (even if named "main")227 CmdlineFiles bool // package built from files listed on command line228 CmdlinePkg bool // package listed on command line229 CmdlinePkgLiteral bool // package listed as literal on command line (not via wildcard)230 Local bool // imported via local path (./ or ../)231 LocalPrefix string // interpret ./ and ../ imports relative to this prefix232 ExeName string // desired name for temporary executable233 FuzzInstrument bool // package should be instrumented for fuzzing234 Cover CoverSetup // coverage mode and other setup info of -cover is being applied to this package235 OmitDebug bool // tell linker not to write debug information236 GobinSubdir bool // install target would be subdir of GOBIN237 InternalImportOk bool // this package may be imported even though it is internal238 BuildInfo *debug.BuildInfo // add this info to package main239 TestmainGo *[]byte // content for _testmain.go240 Embed map[string][]string // //go:embed comment mapping241 OrigImportPath string // original import path before adding '_test' suffix242 PGOProfile string // path to PGO profile243 ForMain string // the main package if this package is built specifically for it244245 Asmflags []string // -asmflags for this package246 Gcflags []string // -gcflags for this package247 Ldflags []string // -ldflags for this package248 Gccgoflags []string // -gccgoflags for this package249}250251// A NoGoError indicates that no Go files for the package were applicable to the252// build for that package.253//254// That may be because there were no files whatsoever, or because all files were255// excluded, or because all non-excluded files were test sources.256type NoGoError struct {257 Package *Package258}259260func (e *NoGoError) Error() string {261 if len(e.Package.IgnoredGoFiles) > 0 {262 // Go files exist, but they were ignored due to build constraints.263 return "build constraints exclude all Go files in " + e.Package.Dir264 }265 if len(e.Package.TestGoFiles)+len(e.Package.XTestGoFiles) > 0 {266 // Test Go files exist, but we're not interested in them.267 // The double-negative is unfortunate but we want e.Package.Dir268 // to appear at the end of error message.269 return "no non-test Go files in " + e.Package.Dir270 }271 return "no Go files in " + e.Package.Dir272}273274// setLoadPackageDataError presents an error found when loading package data275// as a *PackageError. It has special cases for some common errors to improve276// messages shown to users and reduce redundancy.277//278// setLoadPackageDataError returns true if it's safe to load information about279// imported packages, for example, if there was a parse error loading imports280// in one file, but other files are okay.281func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportStack, importPos []token.Position) {282 matchErr, isMatchErr := err.(*search.MatchError)283 if isMatchErr && matchErr.Match.Pattern() == path {284 if matchErr.Match.IsLiteral() {285 // The error has a pattern has a pattern similar to the import path.286 // It may be slightly different (./foo matching example.com/foo),287 // but close enough to seem redundant.288 // Unwrap the error so we don't show the pattern.289 err = matchErr.Err290 }291 }292293 // Replace (possibly wrapped) *build.NoGoError with *load.NoGoError.294 // The latter is more specific about the cause.295 nogoErr, ok := errors.AsType[*build.NoGoError](err)296 if ok {297 if p.Dir == "" && nogoErr.Dir != "" {298 p.Dir = nogoErr.Dir299 }300 err = &NoGoError{Package: p}301 }302303 // Take only the first error from a scanner.ErrorList. PackageError only304 // has room for one position, so we report the first error with a position305 // instead of all of the errors without a position.306 var pos string307 var isScanErr bool308 if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 {309 isScanErr = true // For stack push/pop below.310311 scanPos := scanErr[0].Pos312 scanPos.Filename = base.ShortPath(scanPos.Filename)313 pos = scanPos.String()314 err = errors.New(scanErr[0].Msg)315 }316317 // Report the error on the importing package if the problem is with the import declaration318 // for example, if the package doesn't exist or if the import path is malformed.319 // On the other hand, don't include a position if the problem is with the imported package,320 // for example there are no Go files (NoGoError), or there's a problem in the imported321 // package's source files themselves (scanner errors).322 //323 // TODO(matloob): Perhaps make each of those the errors in the first group324 // (including modload.ImportMissingError, ImportMissingSumError, and the325 // corresponding "cannot find package %q in any of" GOPATH-mode error326 // produced in build.(*Context).Import; modload.AmbiguousImportError,327 // and modload.PackageNotInModuleError; and the malformed module path errors328 // produced in golang.org/x/mod/module.CheckMod) implement an interface329 // to make it easier to check for them? That would save us from having to330 // move the modload errors into this package to avoid a package import cycle,331 // and from having to export an error type for the errors produced in build.332 if !isMatchErr && (nogoErr != nil || isScanErr) {333 stk.Push(ImportInfo{Pkg: path, Pos: extractFirstImport(importPos)})334 defer stk.Pop()335 }336337 p.Error = &PackageError{338 ImportStack: stk.Copy(),339 Pos: pos,340 Err: err,341 }342 p.Incomplete = true343344 top, ok := stk.Top()345 if ok && path != top.Pkg {346 p.Error.setPos(importPos)347 }348}349350// Resolve returns the resolved version of imports,351// which should be p.TestImports or p.XTestImports, NOT p.Imports.352// The imports in p.TestImports and p.XTestImports are not recursively353// loaded during the initial load of p, so they list the imports found in354// the source file, but most processing should be over the vendor-resolved355// import paths. We do this resolution lazily both to avoid file system work356// and because the eventual real load of the test imports (during 'go test')357// can produce better error messages if it starts with the original paths.358// The initial load of p loads all the non-test imports and rewrites359// the vendored paths, so nothing should ever call p.vendored(p.Imports).360func (p *Package) Resolve(s *modload.Loader, imports []string) []string {361 if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] {362 panic("internal error: p.Resolve(p.Imports) called")363 }364 seen := make(map[string]bool)365 var all []string366 for _, path := range imports {367 path = ResolveImportPath(s, p, path)368 if !seen[path] {369 seen[path] = true370 all = append(all, path)371 }372 }373 sort.Strings(all)374 return all375}376377// CoverSetup holds parameters related to coverage setup for a given package (covermode, etc).378type CoverSetup struct {379 Mode string // coverage mode for this package380 GenMeta bool // ask cover tool to emit a static meta data if set381}382383func (p *Package) copyBuild(opts PackageOpts, pp *build.Package) {384 p.Internal.Build = pp385386 if pp.PkgTargetRoot != "" && cfg.BuildPkgdir != "" {387 old := pp.PkgTargetRoot388 pp.PkgRoot = cfg.BuildPkgdir389 pp.PkgTargetRoot = cfg.BuildPkgdir390 if pp.PkgObj != "" {391 pp.PkgObj = filepath.Join(cfg.BuildPkgdir, strings.TrimPrefix(pp.PkgObj, old))392 }393 }394395 p.Dir = pp.Dir396 p.ImportPath = pp.ImportPath397 p.ImportComment = pp.ImportComment398 p.Name = pp.Name399 p.Doc = pp.Doc400 p.Root = pp.Root401 p.ConflictDir = pp.ConflictDir402 p.BinaryOnly = pp.BinaryOnly403404 // TODO? Target405 p.Goroot = pp.Goroot || fips140.Snapshot() && str.HasFilePathPrefix(p.Dir, fips140.Dir())406 p.Standard = p.Goroot && p.ImportPath != "" && search.IsStandardImportPath(p.ImportPath)407 p.GoFiles = pp.GoFiles408 p.CgoFiles = pp.CgoFiles409 p.IgnoredGoFiles = pp.IgnoredGoFiles410 p.InvalidGoFiles = pp.InvalidGoFiles411 p.IgnoredOtherFiles = pp.IgnoredOtherFiles412 p.CFiles = pp.CFiles413 p.CXXFiles = pp.CXXFiles414 p.MFiles = pp.MFiles415 p.HFiles = pp.HFiles416 p.FFiles = pp.FFiles417 p.SFiles = pp.SFiles418 p.SwigFiles = pp.SwigFiles419 p.SwigCXXFiles = pp.SwigCXXFiles420 p.SysoFiles = pp.SysoFiles421 if cfg.BuildMSan {422 // There's no way for .syso files to be built both with and without423 // support for memory sanitizer. Assume they are built without,424 // and drop them.425 p.SysoFiles = nil426 }427 p.CgoCFLAGS = pp.CgoCFLAGS428 p.CgoCPPFLAGS = pp.CgoCPPFLAGS429 p.CgoCXXFLAGS = pp.CgoCXXFLAGS430 p.CgoFFLAGS = pp.CgoFFLAGS431 p.CgoLDFLAGS = pp.CgoLDFLAGS432 p.CgoPkgConfig = pp.CgoPkgConfig433 // We modify p.Imports in place, so make copy now.434 p.Imports = make([]string, len(pp.Imports))435 copy(p.Imports, pp.Imports)436 p.Internal.RawImports = pp.Imports437 p.TestGoFiles = pp.TestGoFiles438 p.TestImports = pp.TestImports439 p.XTestGoFiles = pp.XTestGoFiles440 p.XTestImports = pp.XTestImports441 if opts.IgnoreImports {442 p.Imports = nil443 p.Internal.RawImports = nil444 p.TestImports = nil445 p.XTestImports = nil446 }447 p.EmbedPatterns = pp.EmbedPatterns448 p.TestEmbedPatterns = pp.TestEmbedPatterns449 p.XTestEmbedPatterns = pp.XTestEmbedPatterns450 p.Internal.OrigImportPath = pp.ImportPath451}452453// A PackageError describes an error loading information about a package.454type PackageError struct {455 ImportStack ImportStack // shortest path from package named on command line to this one with position456 Pos string // position of error457 Err error // the error itself458 IsImportCycle bool // the error is an import cycle459 alwaysPrintStack bool // whether to always print the ImportStack460}461462func (p *PackageError) Error() string {463 // TODO(#43696): decide when to print the stack or the position based on464 // the error type and whether the package is in the main module.465 // Document the rationale.466 if p.Pos != "" && (len(p.ImportStack) == 0 || !p.alwaysPrintStack) {467 // Omit import stack. The full path to the file where the error468 // is the most important thing.469 return p.Pos + ": " + p.Err.Error()470 }471472 // If the error is an ImportPathError, and the last path on the stack appears473 // in the error message, omit that path from the stack to avoid repetition.474 // If an ImportPathError wraps another ImportPathError that matches the475 // last path on the stack, we don't omit the path. An error like476 // "package A imports B: error loading C caused by B" would not be clearer477 // if "imports B" were omitted.478 if len(p.ImportStack) == 0 {479 return p.Err.Error()480 }481 var optpos string482 if p.Pos != "" {483 optpos = "\n\t" + p.Pos484 }485 imports := p.ImportStack.Pkgs()486 if p.IsImportCycle {487 imports = p.ImportStack.PkgsWithPos()488 }489 return "package " + strings.Join(imports, "\n\timports ") + optpos + ": " + p.Err.Error()490}491492func (p *PackageError) Unwrap() error { return p.Err }493494// PackageError implements MarshalJSON so that Err is marshaled as a string495// and non-essential fields are omitted.496func (p *PackageError) MarshalJSON() ([]byte, error) {497 perr := struct {498 ImportStack []string // use []string for package names499 Pos string500 Err string501 }{p.ImportStack.Pkgs(), p.Pos, p.Err.Error()}502 return json.Marshal(perr)503}504505func (p *PackageError) setPos(posList []token.Position) {506 if len(posList) == 0 {507 return508 }509 pos := posList[0]510 pos.Filename = base.ShortPath(pos.Filename)511 p.Pos = pos.String()512}513514// ImportPathError is a type of error that prevents a package from being loaded515// for a given import path. When such a package is loaded, a *Package is516// returned with Err wrapping an ImportPathError: the error is attached to517// the imported package, not the importing package.518//519// The string returned by ImportPath must appear in the string returned by520// Error. Errors that wrap ImportPathError (such as PackageError) may omit521// the import path.522type ImportPathError interface {523 error524 ImportPath() string525}526527var (528 _ ImportPathError = (*importError)(nil)529 _ ImportPathError = (*mainPackageError)(nil)530 _ ImportPathError = (*modload.ImportMissingError)(nil)531 _ ImportPathError = (*modload.ImportMissingSumError)(nil)532 _ ImportPathError = (*modload.DirectImportFromImplicitDependencyError)(nil)533)534535type importError struct {536 importPath string537 err error // created with fmt.Errorf538}539540func ImportErrorf(path, format string, args ...any) ImportPathError {541 err := &importError{importPath: path, err: fmt.Errorf(format, args...)}542 if errStr := err.Error(); !strings.Contains(errStr, path) && !strings.Contains(errStr, strconv.Quote(path)) {543 panic(fmt.Sprintf("path %q not in error %q", path, errStr))544 }545 return err546}547548func (e *importError) Error() string {549 return e.err.Error()550}551552func (e *importError) Unwrap() error {553 // Don't return e.err directly, since we're only wrapping an error if %w554 // was passed to ImportErrorf.555 return errors.Unwrap(e.err)556}557558func (e *importError) ImportPath() string {559 return e.importPath560}561562type ImportInfo struct {563 Pkg string564 Pos *token.Position565}566567// An ImportStack is a stack of import paths, possibly with the suffix " (test)" appended.568// The import path of a test package is the import path of the corresponding569// non-test package with the suffix "_test" added.570type ImportStack []ImportInfo571572func NewImportInfo(pkg string, pos *token.Position) ImportInfo {573 return ImportInfo{Pkg: pkg, Pos: pos}574}575576func (s *ImportStack) Push(p ImportInfo) {577 *s = append(*s, p)578}579580func (s *ImportStack) Pop() {581 *s = (*s)[0 : len(*s)-1]582}583584func (s *ImportStack) Copy() ImportStack {585 return slices.Clone(*s)586}587588func (s *ImportStack) Pkgs() []string {589 ss := make([]string, 0, len(*s))590 for _, v := range *s {591 ss = append(ss, v.Pkg)592 }593 return ss594}595596func (s *ImportStack) PkgsWithPos() []string {597 ss := make([]string, 0, len(*s))598 for _, v := range *s {599 if v.Pos != nil {600 ss = append(ss, v.Pkg+" from "+filepath.Base(v.Pos.Filename))601 } else {602 ss = append(ss, v.Pkg)603 }604 }605 return ss606}607608func (s *ImportStack) Top() (ImportInfo, bool) {609 if len(*s) == 0 {610 return ImportInfo{}, false611 }612 return (*s)[len(*s)-1], true613}614615// shorterThan reports whether sp is shorter than t.616// We use this to record the shortest import sequence617// that leads to a particular package.618func (sp *ImportStack) shorterThan(t []string) bool {619 s := *sp620 if len(s) != len(t) {621 return len(s) < len(t)622 }623 // If they are the same length, settle ties using string ordering.624 for i := range s {625 siPkg := s[i].Pkg626 if siPkg != t[i] {627 return siPkg < t[i]628 }629 }630 return false // they are equal631}632633// dirToImportPath returns the pseudo-import path we use for a package634// outside the Go path. It begins with _/ and then contains the full path635// to the directory. If the package lives in c:\home\gopher\my\pkg then636// the pseudo-import path is _/c_/home/gopher/my/pkg.637// Using a pseudo-import path like this makes the ./ imports no longer638// a special case, so that all the code to deal with ordinary imports works639// automatically.640func dirToImportPath(dir string) string {641 return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir)))642}643644func makeImportValid(r rune) rune {645 // Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport.646 const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"647 if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {648 return '_'649 }650 return r651}652653// Mode flags for loadImport and download (in get.go).654const (655 // ResolveImport means that loadImport should do import path expansion.656 // That is, ResolveImport means that the import path came from657 // a source file and has not been expanded yet to account for658 // vendoring or possible module adjustment.659 // Every import path should be loaded initially with ResolveImport,660 // and then the expanded version (for example with the /vendor/ in it)661 // gets recorded as the canonical import path. At that point, future loads662 // of that package must not pass ResolveImport, because663 // disallowVendor will reject direct use of paths containing /vendor/.664 ResolveImport = 1 << iota665666 // ResolveModule is for download (part of "go get") and indicates667 // that the module adjustment should be done, but not vendor adjustment.668 ResolveModule669670 // GetTestDeps is for download (part of "go get") and indicates671 // that test dependencies should be fetched too.672 GetTestDeps673674 // The remainder are internal modes for calls to loadImport.675676 // cmdlinePkg is for a package mentioned on the command line.677 cmdlinePkg678679 // cmdlinePkgLiteral is for a package mentioned on the command line680 // without using any wildcards or meta-patterns.681 cmdlinePkgLiteral682683 // allow simd/internal/bridge684 allowSimdInternalBridge685)686687// LoadPackage does Load import, but without a parent package load context688func LoadPackage(ld *modload.Loader, ctx context.Context, opts PackageOpts, path, srcDir string, stk *ImportStack, importPos []token.Position, mode int) *Package {689 p, err := loadImport(ld, ctx, opts, nil, path, srcDir, nil, stk, importPos, mode)690 if err != nil {691 base.Fatalf("internal error: loadImport of %q with nil parent returned an error", path)692 }693 return p694}695696// loadImport scans the directory named by path, which must be an import path,697// but possibly a local import path (an absolute file system path or one beginning698// with ./ or ../). A local relative path is interpreted relative to srcDir.699// It returns a *Package describing the package found in that directory.700// loadImport does not set tool flags and should only be used by701// this package, as part of a bigger load operation.702// The returned PackageError, if any, describes why parent is not allowed703// to import the named package, with the error referring to importPos.704// The PackageError can only be non-nil when parent is not nil.705func loadImport(ld *modload.Loader, ctx context.Context, opts PackageOpts, pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) (*Package, *PackageError) {706 ctx, span := trace.StartSpan(ctx, "modload.loadImport "+path)707 defer span.Done()708709 if path == "" {710 panic("LoadImport called with empty package path")711 }712713 var parentPath, parentRoot string714 parentIsStd := false715 if parent != nil {716 parentPath = parent.ImportPath717 parentRoot = parent.Root718 parentIsStd = parent.Standard719 }720 bp, loaded, err := loadPackageData(ld, ctx, path, parentPath, srcDir, parentRoot, parentIsStd, mode)721 if loaded && pre != nil && !opts.IgnoreImports {722 pre.preloadImports(ld, ctx, opts, bp.Imports, bp)723 }724 if bp == nil {725 p := &Package{726 PackagePublic: PackagePublic{727 ImportPath: path,728 Incomplete: true,729 },730 }731 if importErr, ok := err.(ImportPathError); !ok || importErr.ImportPath() != path {732 // Only add path to the error's import stack if it's not already present733 // in the error.734 //735 // TODO(bcmills): setLoadPackageDataError itself has a similar Push / Pop736 // sequence that empirically doesn't trigger for these errors, guarded by737 // a somewhat complex condition. Figure out how to generalize that738 // condition and eliminate the explicit calls here.739 stk.Push(ImportInfo{Pkg: path, Pos: extractFirstImport(importPos)})740 defer stk.Pop()741 }742 p.setLoadPackageDataError(err, path, stk, nil)743 setToolFlags(ld, p)744 return p, nil745 }746747 setCmdline := func(p *Package) {748 if mode&cmdlinePkg != 0 {749 p.Internal.CmdlinePkg = true750 }751 if mode&cmdlinePkgLiteral != 0 {752 p.Internal.CmdlinePkgLiteral = true753 }754 }755756 importPath := bp.ImportPath757 var p *Package758 if cp := ld.PackageCache()[importPath]; cp != nil {759 p = cp.(*Package)760 stk.Push(ImportInfo{Pkg: path, Pos: extractFirstImport(importPos)})761 p = reusePackage(p, stk)762 stk.Pop()763 setCmdline(p)764 } else {765 p = new(Package)766 p.Internal.Local = build.IsLocalImport(path)767 p.ImportPath = importPath768 ld.PackageCache()[importPath] = p769770 setCmdline(p)771 setToolFlags(ld, p)772773 // Load package.774 // loadPackageData may return bp != nil even if an error occurs,775 // in order to return partial information.776 p.load(ld, ctx, opts, path, stk, importPos, bp, err)777778 if !cfg.ModulesEnabled && path != cleanImport(path) {779 p.Error = &PackageError{780 ImportStack: stk.Copy(),781 Err: ImportErrorf(path, "non-canonical import path %q: should be %q", path, pathpkg.Clean(path)),782 }783 p.Incomplete = true784 p.Error.setPos(importPos)785 }786 }787788 if mode&allowSimdInternalBridge == 0 || path != SimdBridgePkg { // Special case for just this import.789 // Checked on every import because the rules depend on the code doing the importing.790 if perr := disallowInternal(ld, ctx, srcDir, parent, parentPath, p, stk); perr != nil {791 perr.setPos(importPos)792 return p, perr793 }794 }795 if mode&ResolveImport != 0 {796 if perr := disallowVendor(srcDir, path, parentPath, p, stk); perr != nil {797 perr.setPos(importPos)798 return p, perr799 }800 }801802 if p.Name == "main" && parent != nil && parent.Dir != p.Dir {803 perr := &PackageError{804 ImportStack: stk.Copy(),805 Err: ImportErrorf(path, "import %q is a program, not an importable package", path),806 }807 perr.setPos(importPos)808 return p, perr809 }810811 if p.Internal.Local && parent != nil && !parent.Internal.Local {812 var err error813 if path == "." {814 err = ImportErrorf(path, "%s: cannot import current directory", path)815 } else {816 err = ImportErrorf(path, "local import %q in non-local package", path)817 }818 perr := &PackageError{819 ImportStack: stk.Copy(),820 Err: err,821 }822 perr.setPos(importPos)823 return p, perr824 }825826 return p, nil827}828829func extractFirstImport(importPos []token.Position) *token.Position {830 if len(importPos) == 0 {831 return nil832 }833 return &importPos[0]834}835836// loadPackageData loads information needed to construct a *Package. The result837// is cached, and later calls to loadPackageData for the same package will return838// the same data.839//840// loadPackageData returns a non-nil package even if err is non-nil unless841// the package path is malformed (for example, the path contains "mod/" or "@").842//843// loadPackageData returns a boolean, loaded, which is true if this is the844// first time the package was loaded. Callers may preload imports in this case.845func loadPackageData(ld *modload.Loader, ctx context.Context, path, parentPath, parentDir, parentRoot string, parentIsStd bool, mode int) (bp *build.Package, loaded bool, err error) {846 ctx, span := trace.StartSpan(ctx, "load.loadPackageData "+path)847 defer span.Done()848849 if path == "" {850 panic("loadPackageData called with empty package path")851 }852853 if strings.HasPrefix(path, "mod/") {854 // Paths beginning with "mod/" might accidentally855 // look in the module cache directory tree in $GOPATH/pkg/mod/.856 // This prefix is owned by the Go core for possible use in the857 // standard library (since it does not begin with a domain name),858 // so it's OK to disallow entirely.859 return nil, false, fmt.Errorf("disallowed import path %q", path)860 }861862 if strings.Contains(path, "@") {863 return nil, false, errors.New("can only use path@version syntax with 'go get' and 'go install' in module-aware mode")864 }865866 // Determine canonical package path and directory.867 // For a local import the identifier is the pseudo-import path868 // we create from the full directory to the package.869 // Otherwise it is the usual import path.870 // For vendored imports, it is the expanded form.871 //872 // Note that when modules are enabled, local import paths are normally873 // canonicalized by modload.LoadPackages before now. However, if there's an874 // error resolving a local path, it will be returned untransformed875 // so that 'go list -e' reports something useful.876 importKey := importSpec{877 path: path,878 parentPath: parentPath,879 parentDir: parentDir,880 parentRoot: parentRoot,881 parentIsStd: parentIsStd,882 mode: mode,883 }884 r := resolvedImportCache.Do(importKey, func() resolvedImport {885 var r resolvedImport886 if newPath, dir, ok := fips140.ResolveImport(path); ok {887 r.path = newPath888 r.dir = dir889 } else if cfg.ModulesEnabled {890 r.dir, r.path, r.err = modload.Lookup(ld, parentPath, parentIsStd, path)891 } else if build.IsLocalImport(path) {892 r.dir = filepath.Join(parentDir, path)893 r.path = dirToImportPath(r.dir)894 } else if mode&ResolveImport != 0 {895 // We do our own path resolution, because we want to896 // find out the key to use in packageCache without the897 // overhead of repeated calls to buildContext.Import.898 // The code is also needed in a few other places anyway.899 r.path = resolveImportPath(ld, path, parentPath, parentDir, parentRoot, parentIsStd)900 } else if mode&ResolveModule != 0 {901 r.path = moduleImportPath(path, parentPath, parentDir, parentRoot)902 }903 if r.path == "" {904 r.path = path905 }906 return r907 })908 // Invariant: r.path is set to the resolved import path. If the path cannot909 // be resolved, r.path is set to path, the source import path.910 // r.path is never empty.911912 // Load the package from its directory. If we already found the package's913 // directory when resolving its import path, use that.914 p, err := packageDataCache.Do(r.path, func() (*build.Package, error) {915 loaded = true916 var data struct {917 p *build.Package918 err error919 }920 if r.dir != "" {921 var buildMode build.ImportMode922 buildContext := cfg.BuildContext923 if !cfg.ModulesEnabled {924 buildMode = build.ImportComment925 } else {926 buildContext.GOPATH = "" // Clear GOPATH so packages are imported as pure module packages927 }928 modroot := modload.PackageModRoot(ld, ctx, r.path)929 if modroot == "" && str.HasFilePathPrefix(r.dir, cfg.GOROOTsrc) {930 modroot = cfg.GOROOTsrc931 gorootSrcCmd := filepath.Join(cfg.GOROOTsrc, "cmd")932 if str.HasFilePathPrefix(r.dir, gorootSrcCmd) {933 modroot = gorootSrcCmd934 }935 }936 if modroot != "" {937 if rp, err := modindex.GetPackage(modroot, r.dir); err == nil {938 data.p, data.err = rp.Import(cfg.BuildContext, buildMode)939 goto Happy940 } else if !errors.Is(err, modindex.ErrNotIndexed) {941 base.Fatal(err)942 }943 }944 data.p, data.err = buildContext.ImportDir(r.dir, buildMode)945 Happy:946 if cfg.ModulesEnabled {947 // Override data.p.Root, since ImportDir sets it to $GOPATH, if948 // the module is inside $GOPATH/src.949 if info := modload.PackageModuleInfo(ld, ctx, path); info != nil {950 data.p.Root = info.Dir951 }952 }953 if r.err != nil {954 if data.err != nil {955 // ImportDir gave us one error, and the module loader gave us another.956 // We arbitrarily choose to keep the error from ImportDir because957 // that's what our tests already expect, and it seems to provide a bit958 // more detail in most cases.959 } else if errors.Is(r.err, imports.ErrNoGo) {960 // ImportDir said there were files in the package, but the module961 // loader said there weren't. Which one is right?962 // Without this special-case hack, the TestScript/test_vet case fails963 // on the vetfail/p1 package (added in CL 83955).964 // Apparently, imports.ShouldBuild biases toward rejecting files965 // with invalid build constraints, whereas ImportDir biases toward966 // accepting them.967 //968 // TODO(#41410: Figure out how this actually ought to work and fix969 // this mess).970 } else {971 data.err = r.err972 }973 }974 } else if r.err != nil {975 data.p = new(build.Package)976 data.err = r.err977 } else if cfg.ModulesEnabled && path != "unsafe" {978 data.p = new(build.Package)979 data.err = fmt.Errorf("unknown import path %q: internal error: module loader did not resolve import", r.path)980 } else {981 buildMode := build.ImportComment982 if mode&ResolveImport == 0 || r.path != path {983 // Not vendoring, or we already found the vendored path.984 buildMode |= build.IgnoreVendor985 }986 data.p, data.err = cfg.BuildContext.Import(r.path, parentDir, buildMode)987 }988 data.p.ImportPath = r.path989990 // Set data.p.BinDir in cases where go/build.Context.Import991 // may give us a path we don't want.992 if !data.p.Goroot {993 if cfg.GOBIN != "" {994 data.p.BinDir = cfg.GOBIN995 } else if cfg.ModulesEnabled {996 data.p.BinDir = modload.BinDir(ld)997 }998 }9991000 if !cfg.ModulesEnabled && data.err == nil &&1001 data.p.ImportComment != "" && data.p.ImportComment != path &&1002 !strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") {1003 data.err = fmt.Errorf("code in directory %s expects import %q", data.p.Dir, data.p.ImportComment)1004 }1005 return data.p, data.err1006 })10071008 return p, loaded, err1009}10101011// importSpec describes an import declaration in source code. It is used as a1012// cache key for resolvedImportCache.1013type importSpec struct {1014 path string1015 parentPath, parentDir, parentRoot string1016 parentIsStd bool1017 mode int1018}10191020// resolvedImport holds a canonical identifier for a package. It may also contain1021// a path to the package's directory and an error if one occurred. resolvedImport1022// is the value type in resolvedImportCache.1023type resolvedImport struct {1024 path, dir string1025 err error1026}10271028// resolvedImportCache maps import strings to canonical package names.1029var resolvedImportCache par.Cache[importSpec, resolvedImport]10301031// packageDataCache maps canonical package names (string) to package metadata.1032var packageDataCache par.ErrCache[string, *build.Package]10331034// preloadWorkerCount is the number of concurrent goroutines that can load1035// packages. Experimentally, there are diminishing returns with more than1036// 4 workers. This was measured on the following machines.1037//1038// * MacBookPro with a 4-core Intel Core i7 CPU1039// * Linux workstation with 6-core Intel Xeon CPU1040// * Linux workstation with 24-core Intel Xeon CPU1041//1042// It is very likely (though not confirmed) that this workload is limited1043// by memory bandwidth. We don't have a good way to determine the number of1044// workers that would saturate the bus though, so runtime.GOMAXPROCS1045// seems like a reasonable default.1046var preloadWorkerCount = runtime.GOMAXPROCS(0)10471048// preload holds state for managing concurrent preloading of package data.1049//1050// A preload should be created with newPreload before loading a large1051// package graph. flush must be called when package loading is complete1052// to ensure preload goroutines are no longer active. This is necessary1053// because of global mutable state that cannot safely be read and written1054// concurrently. In particular, packageDataCache may be cleared by "go get"1055// in GOPATH mode, and modload.loaded (accessed via modload.Lookup) may be1056// modified by modload.LoadPackages.1057type preload struct {1058 cancel chan struct{}1059 sema chan struct{}1060}10611062// newPreload creates a new preloader. flush must be called later to avoid1063// accessing global state while it is being modified.1064func newPreload() *preload {1065 pre := &preload{1066 cancel: make(chan struct{}),1067 sema: make(chan struct{}, preloadWorkerCount),1068 }1069 return pre1070}10711072// preloadMatches loads data for package paths matched by patterns.1073// When preloadMatches returns, some packages may not be loaded yet, but1074// loadPackageData and loadImport are always safe to call.1075func (pre *preload) preloadMatches(ld *modload.Loader, ctx context.Context, opts PackageOpts, matches []*search.Match) {1076 for _, m := range matches {1077 for _, pkg := range m.Pkgs {1078 select {1079 case <-pre.cancel:1080 return1081 case pre.sema <- struct{}{}:1082 go func(pkg string) {1083 mode := 0 // don't use vendoring or module import resolution1084 bp, loaded, err := loadPackageData(ld, ctx, pkg, "", base.Cwd(), "", false, mode)1085 <-pre.sema1086 if bp != nil && loaded && err == nil && !opts.IgnoreImports {1087 pre.preloadImports(ld, ctx, opts, bp.Imports, bp)1088 }1089 }(pkg)1090 }1091 }1092 }1093}10941095// preloadImports queues a list of imports for preloading.1096// When preloadImports returns, some packages may not be loaded yet,1097// but loadPackageData and loadImport are always safe to call.1098func (pre *preload) preloadImports(ld *modload.Loader, ctx context.Context, opts PackageOpts, imports []string, parent *build.Package) {1099 parentIsStd := parent.Goroot && parent.ImportPath != "" && search.IsStandardImportPath(parent.ImportPath)1100 for _, path := range imports {1101 if path == "C" || path == "unsafe" {1102 continue1103 }1104 select {1105 case <-pre.cancel:1106 return1107 case pre.sema <- struct{}{}:1108 go func(path string) {1109 bp, loaded, err := loadPackageData(ld, ctx, path, parent.ImportPath, parent.Dir, parent.Root, parentIsStd, ResolveImport)1110 <-pre.sema1111 if bp != nil && loaded && err == nil && !opts.IgnoreImports {1112 pre.preloadImports(ld, ctx, opts, bp.Imports, bp)1113 }1114 }(path)1115 }1116 }1117}11181119// flush stops pending preload operations. flush blocks until preload calls to1120// loadPackageData have completed. The preloader will not make any new calls1121// to loadPackageData.1122func (pre *preload) flush() {1123 // flush is usually deferred.1124 // Don't hang program waiting for workers on panic.1125 if v := recover(); v != nil {1126 panic(v)1127 }11281129 close(pre.cancel)1130 for i := 0; i < preloadWorkerCount; i++ {1131 pre.sema <- struct{}{}1132 }1133}11341135func cleanImport(path string) string {1136 orig := path1137 path = pathpkg.Clean(path)1138 if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") {1139 path = "./" + path1140 }1141 return path1142}11431144var isDirCache par.Cache[string, bool]11451146func isDir(path string) bool {1147 return isDirCache.Do(path, func() bool {1148 fi, err := fsys.Stat(path)1149 return err == nil && fi.IsDir()1150 })1151}11521153// ResolveImportPath returns the true meaning of path when it appears in parent.1154// There are two different resolutions applied.1155// First, there is Go 1.5 vendoring (golang.org/s/go15vendor).1156// If vendor expansion doesn't trigger, then the path is also subject to1157// Go 1.11 module legacy conversion (golang.org/issue/25069).1158func ResolveImportPath(s *modload.Loader, parent *Package, path string) (found string) {1159 var parentPath, parentDir, parentRoot string1160 parentIsStd := false1161 if parent != nil {1162 parentPath = parent.ImportPath1163 parentDir = parent.Dir1164 parentRoot = parent.Root1165 parentIsStd = parent.Standard1166 }1167 return resolveImportPath(s, path, parentPath, parentDir, parentRoot, parentIsStd)1168}11691170func resolveImportPath(s *modload.Loader, path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) {1171 if cfg.ModulesEnabled {1172 if _, p, e := modload.Lookup(s, parentPath, parentIsStd, path); e == nil {1173 return p1174 }1175 return path1176 }1177 found = vendoredImportPath(path, parentPath, parentDir, parentRoot)1178 if found != path {1179 return found1180 }1181 return moduleImportPath(path, parentPath, parentDir, parentRoot)1182}11831184// dirAndRoot returns the source directory and workspace root1185// for the package p, guaranteeing that root is a path prefix of dir.1186func dirAndRoot(path string, dir, root string) (string, string) {1187 origDir, origRoot := dir, root1188 dir = filepath.Clean(dir)1189 root = filepath.Join(root, "src")1190 if !str.HasFilePathPrefix(dir, root) || path != "command-line-arguments" && filepath.Join(root, path) != dir {1191 // Look for symlinks before reporting error.1192 dir = expandPath(dir)1193 root = expandPath(root)1194 }11951196 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 {1197 debug.PrintStack()1198 base.Fatalf("unexpected directory layout:\n"+1199 " import path: %s\n"+1200 " root: %s\n"+1201 " dir: %s\n"+1202 " expand root: %s\n"+1203 " expand dir: %s\n"+1204 " separator: %s",1205 path,1206 filepath.Join(origRoot, "src"),1207 filepath.Clean(origDir),1208 origRoot,1209 origDir,1210 string(filepath.Separator))1211 }12121213 return dir, root1214}12151216// vendoredImportPath returns the vendor-expansion of path when it appears in parent.1217// If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path,1218// x/vendor/path, vendor/path, or else stay path if none of those exist.1219// vendoredImportPath returns the expanded path or, if no expansion is found, the original.1220func vendoredImportPath(path, parentPath, parentDir, parentRoot string) (found string) {1221 if parentRoot == "" {1222 return path1223 }12241225 dir, root := dirAndRoot(parentPath, parentDir, parentRoot)12261227 vpath := "vendor/" + path1228 for i := len(dir); i >= len(root); i-- {1229 if i < len(dir) && dir[i] != filepath.Separator {1230 continue1231 }1232 // Note: checking for the vendor directory before checking1233 // for the vendor/path directory helps us hit the1234 // isDir cache more often. It also helps us prepare a more useful1235 // list of places we looked, to report when an import is not found.1236 if !isDir(filepath.Join(dir[:i], "vendor")) {1237 continue1238 }1239 targ := filepath.Join(dir[:i], vpath)1240 if isDir(targ) && hasGoFiles(targ) {1241 importPath := parentPath1242 if importPath == "command-line-arguments" {1243 // If parent.ImportPath is 'command-line-arguments'.1244 // set to relative directory to root (also chopped root directory)1245 importPath = dir[len(root)+1:]1246 }1247 // We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy.1248 // We know the import path for parent's dir.1249 // We chopped off some number of path elements and1250 // added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path.1251 // Now we want to know the import path for that directory.1252 // Construct it by chopping the same number of path elements1253 // (actually the same number of bytes) from parent's import path1254 // and then append /vendor/path.1255 chopped := len(dir) - i1256 if chopped == len(importPath)+1 {1257 // We walked up from c:\gopath\src\foo\bar1258 // and found c:\gopath\src\vendor\path.1259 // We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7).1260 // Use "vendor/path" without any prefix.1261 return vpath1262 }1263 return importPath[:len(importPath)-chopped] + "/" + vpath1264 }1265 }1266 return path1267}12681269var (1270 modulePrefix = []byte("\nmodule ")1271 goModPathCache par.Cache[string, string]1272)12731274// goModPath returns the module path in the go.mod in dir, if any.1275func goModPath(dir string) (path string) {1276 return goModPathCache.Do(dir, func() string {1277 data, err := os.ReadFile(filepath.Join(dir, "go.mod"))1278 if err != nil {1279 return ""1280 }1281 var i int1282 if bytes.HasPrefix(data, modulePrefix[1:]) {1283 i = 01284 } else {1285 i = bytes.Index(data, modulePrefix)1286 if i < 0 {1287 return ""1288 }1289 i++1290 }1291 line := data[i:]12921293 // Cut line at \n, drop trailing \r if present.1294 if j := bytes.IndexByte(line, '\n'); j >= 0 {1295 line = line[:j]1296 }1297 if line[len(line)-1] == '\r' {1298 line = line[:len(line)-1]1299 }1300 line = line[len("module "):]13011302 // If quoted, unquote.1303 path = strings.TrimSpace(string(line))1304 if path != "" && path[0] == '"' {1305 s, err := strconv.Unquote(path)1306 if err != nil {1307 return ""1308 }1309 path = s1310 }1311 return path1312 })1313}13141315// findVersionElement returns the slice indices of the final version element /vN in path.1316// If there is no such element, it returns -1, -1.1317func findVersionElement(path string) (i, j int) {1318 j = len(path)1319 for i = len(path) - 1; i >= 0; i-- {1320 if path[i] == '/' {1321 if isVersionElement(path[i+1 : j]) {1322 return i, j1323 }1324 j = i1325 }1326 }1327 return -1, -11328}13291330// isVersionElement reports whether s is a well-formed path version element:1331// v2, v3, v10, etc, but not v0, v05, v1.1332func isVersionElement(s string) bool {1333 if len(s) < 2 || s[0] != 'v' || s[1] == '0' || s[1] == '1' && len(s) == 2 {1334 return false1335 }1336 for i := 1; i < len(s); i++ {1337 if s[i] < '0' || '9' < s[i] {1338 return false1339 }1340 }1341 return true1342}13431344// moduleImportPath translates import paths found in go modules1345// back down to paths that can be resolved in ordinary builds.1346//1347// Define “new” code as code with a go.mod file in the same directory1348// or a parent directory. If an import in new code says x/y/v2/z but1349// x/y/v2/z does not exist and x/y/go.mod says “module x/y/v2”,1350// then go build will read the import as x/y/z instead.1351// See golang.org/issue/25069.1352func moduleImportPath(path, parentPath, parentDir, parentRoot string) (found string) {1353 if parentRoot == "" {1354 return path1355 }13561357 // If there are no vN elements in path, leave it alone.1358 // (The code below would do the same, but only after1359 // some other file system accesses that we can avoid1360 // here by returning early.)1361 if i, _ := findVersionElement(path); i < 0 {1362 return path1363 }13641365 dir, root := dirAndRoot(parentPath, parentDir, parentRoot)13661367 // Consider dir and parents, up to and including root.1368 for i := len(dir); i >= len(root); i-- {1369 if i < len(dir) && dir[i] != filepath.Separator {1370 continue1371 }1372 if goModPath(dir[:i]) != "" {1373 goto HaveGoMod1374 }1375 }1376 // This code is not in a tree with a go.mod,1377 // so apply no changes to the path.1378 return path13791380HaveGoMod:1381 // This import is in a tree with a go.mod.1382 // Allow it to refer to code in GOPATH/src/x/y/z as x/y/v2/z1383 // if GOPATH/src/x/y/go.mod says module "x/y/v2",13841385 // If x/y/v2/z exists, use it unmodified.1386 if bp, _ := cfg.BuildContext.Import(path, "", build.IgnoreVendor); bp.Dir != "" {1387 return path1388 }13891390 // Otherwise look for a go.mod supplying a version element.1391 // Some version-like elements may appear in paths but not1392 // be module versions; we skip over those to look for module1393 // versions. For example the module m/v2 might have a1394 // package m/v2/api/v1/foo.1395 limit := len(path)1396 for limit > 0 {1397 i, j := findVersionElement(path[:limit])1398 if i < 0 {1399 return path1400 }1401 if bp, _ := cfg.BuildContext.Import(path[:i], "", build.IgnoreVendor); bp.Dir != "" {1402 if mpath := goModPath(bp.Dir); mpath != "" {1403 // Found a valid go.mod file, so we're stopping the search.1404 // If the path is m/v2/p and we found m/go.mod that says1405 // "module m/v2", then we return "m/p".1406 if mpath == path[:j] {1407 return path[:i] + path[j:]1408 }1409 // Otherwise just return the original path.1410 // We didn't find anything worth rewriting,1411 // and the go.mod indicates that we should1412 // not consider parent directories.1413 return path1414 }1415 }1416 limit = i1417 }1418 return path1419}14201421// hasGoFiles reports whether dir contains any files with names ending in .go.1422// For a vendor check we must exclude directories that contain no .go files.1423// Otherwise it is not possible to vendor just a/b/c and still import the1424// non-vendored a/b. See golang.org/issue/13832.1425func hasGoFiles(dir string) bool {1426 files, _ := os.ReadDir(dir)1427 for _, f := range files {1428 if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") {1429 return true1430 }1431 }1432 return false1433}14341435// reusePackage reuses package p to satisfy the import at the top1436// of the import stack stk. If this use causes an import loop,1437// reusePackage updates p's error information to record the loop.1438func reusePackage(p *Package, stk *ImportStack) *Package {1439 // We use p.Internal.Imports==nil to detect a package that1440 // is in the midst of its own loadPackage call1441 // (all the recursion below happens before p.Internal.Imports gets set).1442 if p.Internal.Imports == nil {1443 if p.Error == nil {1444 p.Error = &PackageError{1445 ImportStack: stk.Copy(),1446 Err: errors.New("import cycle not allowed"),1447 IsImportCycle: true,1448 }1449 } else if !p.Error.IsImportCycle {1450 // If the error is already set, but it does not indicate that1451 // we are in an import cycle, set IsImportCycle so that we don't1452 // end up stuck in a loop down the road.1453 p.Error.IsImportCycle = true1454 }1455 p.Incomplete = true1456 }1457 // Don't rewrite the import stack in the error if we have an import cycle.1458 // If we do, we'll lose the path that describes the cycle.1459 if p.Error != nil && p.Error.ImportStack != nil &&1460 !p.Error.IsImportCycle && stk.shorterThan(p.Error.ImportStack.Pkgs()) {1461 p.Error.ImportStack = stk.Copy()1462 }1463 return p1464}14651466// disallowInternal checks that srcDir (containing package importerPath, if non-empty)1467// is allowed to import p.1468// If the import is allowed, disallowInternal returns the original package p.1469// If not, it returns a new package containing just an appropriate error.1470func disallowInternal(ld *modload.Loader, ctx context.Context, srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *PackageError {1471 // golang.org/s/go14internal:1472 // An import of a path containing the element “internal”1473 // is disallowed if the importing code is outside the tree1474 // rooted at the parent of the “internal” directory.14751476 // There was an error loading the package; stop here.1477 if p.Error != nil {1478 return nil1479 }14801481 // The generated 'testmain' package is allowed to access testing/internal/...,1482 // as if it were generated into the testing directory tree1483 // (it's actually in a temporary directory outside any Go tree).1484 // This cleans up a former kludge in passing functionality to the testing package.1485 if str.HasPathPrefix(p.ImportPath, "testing/internal") && importerPath == "testmain" {1486 return nil1487 }14881489 // We can't check standard packages with gccgo.1490 if cfg.BuildContext.Compiler == "gccgo" && p.Standard {1491 return nil1492 }14931494 // The sort package depends on internal/reflectlite, but during bootstrap1495 // the path rewriting causes the normal internal checks to fail.1496 // Instead, just ignore the internal rules during bootstrap.1497 if p.Standard && strings.HasPrefix(importerPath, "bootstrap/") {1498 return nil1499 }15001501 // importerPath is empty: we started1502 // with a name given on the command line, not an1503 // import. Anything listed on the command line is fine.1504 if importerPath == "" {1505 return nil1506 }15071508 // Check for "internal" element: three cases depending on begin of string and/or end of string.1509 i, ok := findInternal(p.ImportPath)1510 if !ok {1511 return nil1512 }15131514 // Internal is present.1515 // Map import path back to directory corresponding to parent of internal.1516 if i > 0 {1517 i-- // rewind over slash in ".../internal"1518 }15191520 // FIPS-140 snapshots are special, because they comes from a non-GOROOT1521 // directory, so the usual directory rules don't work apply, or rather they1522 // apply differently depending on whether we are using a snapshot or the1523 // in-tree copy of the code. We apply a consistent rule here:1524 // crypto/internal/fips140 can only see crypto/internal, never top-of-tree internal.1525 // Similarly, crypto/... can see crypto/internal/fips140 even though the usual rules1526 // would not allow it in snapshot mode.1527 if str.HasPathPrefix(importerPath, "crypto") && str.HasPathPrefix(p.ImportPath, "crypto/internal/fips140") {1528 return nil // crypto can use crypto/internal/fips1401529 }1530 if str.HasPathPrefix(importerPath, "crypto/internal/fips140") {1531 if str.HasPathPrefix(p.ImportPath, "crypto/internal") {1532 return nil // crypto/internal/fips140 can use crypto/internal1533 }1534 goto Error1535 }15361537 if p.Module == nil {1538 parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]15391540 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {1541 return nil1542 }15431544 // Look for symlinks before reporting error.1545 srcDir = expandPath(srcDir)1546 parent = expandPath(parent)1547 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {1548 return nil1549 }1550 } else {1551 // p is in a module, so make it available based on the importer's import path instead1552 // of the file path (https://golang.org/issue/23970).1553 if importer.Internal.CmdlineFiles {1554 // The importer is a list of command-line files.1555 // Pretend that the import path is the import path of the1556 // directory containing them.1557 // If the directory is outside the main modules, this will resolve to ".",1558 // which is not a prefix of any valid module.1559 importerPath, _ = ld.MainModules.DirImportPath(ld, ctx, importer.Dir)1560 }1561 parentOfInternal := p.ImportPath[:i]1562 if str.HasPathPrefix(importerPath, parentOfInternal) {1563 return nil1564 }1565 }15661567Error:1568 // Internal is present, and srcDir is outside parent's tree. Not allowed.1569 perr := &PackageError{1570 alwaysPrintStack: true,1571 ImportStack: stk.Copy(),1572 Err: ImportErrorf(p.ImportPath, "use of internal package %s not allowed", p.ImportPath),1573 }1574 return perr1575}15761577// findInternal looks for the final "internal" path element in the given import path.1578// If there isn't one, findInternal returns ok=false.1579// Otherwise, findInternal returns ok=true and the index of the "internal".1580func findInternal(path string) (index int, ok bool) {1581 // Three cases, depending on internal at start/end of string or not.1582 // The order matters: we must return the index of the final element,1583 // because the final one produces the most restrictive requirement1584 // on the importer.1585 switch {1586 case strings.HasSuffix(path, "/internal"):1587 return len(path) - len("internal"), true1588 case strings.Contains(path, "/internal/"):1589 return strings.LastIndex(path, "/internal/") + 1, true1590 case path == "internal", strings.HasPrefix(path, "internal/"):1591 return 0, true1592 }1593 return 0, false1594}15951596// disallowVendor checks that srcDir is allowed to import p as path.1597// If the import is allowed, disallowVendor returns the original package p.1598// If not, it returns a PackageError.1599func disallowVendor(srcDir string, path string, importerPath string, p *Package, stk *ImportStack) *PackageError {1600 // If the importerPath is empty, we started1601 // with a name given on the command line, not an1602 // import. Anything listed on the command line is fine.1603 if importerPath == "" {1604 return nil1605 }16061607 if perr := disallowVendorVisibility(srcDir, p, importerPath, stk); perr != nil {1608 return perr1609 }16101611 // Paths like x/vendor/y must be imported as y, never as x/vendor/y.1612 if i, ok := FindVendor(path); ok {1613 perr := &PackageError{1614 ImportStack: stk.Copy(),1615 Err: ImportErrorf(path, "%s must be imported as %s", path, path[i+len("vendor/"):]),1616 }1617 return perr1618 }16191620 return nil1621}16221623// disallowVendorVisibility checks that srcDir is allowed to import p.1624// The rules are the same as for /internal/ except that a path ending in /vendor1625// is not subject to the rules, only subdirectories of vendor.1626// This allows people to have packages and commands named vendor,1627// for maximal compatibility with existing source trees.1628func disallowVendorVisibility(srcDir string, p *Package, importerPath string, stk *ImportStack) *PackageError {1629 // The stack does not include p.ImportPath.1630 // If there's nothing on the stack, we started1631 // with a name given on the command line, not an1632 // import. Anything listed on the command line is fine.1633 if importerPath == "" {1634 return nil1635 }16361637 // Check for "vendor" element.1638 i, ok := FindVendor(p.ImportPath)1639 if !ok {1640 return nil1641 }16421643 // Vendor is present.1644 // Map import path back to directory corresponding to parent of vendor.1645 if i > 0 {1646 i-- // rewind over slash in ".../vendor"1647 }1648 truncateTo := i + len(p.Dir) - len(p.ImportPath)1649 if truncateTo < 0 || len(p.Dir) < truncateTo {1650 return nil1651 }1652 parent := p.Dir[:truncateTo]1653 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {1654 return nil1655 }16561657 // Look for symlinks before reporting error.1658 srcDir = expandPath(srcDir)1659 parent = expandPath(parent)1660 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {1661 return nil1662 }16631664 // Vendor is present, and srcDir is outside parent's tree. Not allowed.16651666 perr := &PackageError{1667 ImportStack: stk.Copy(),1668 Err: errors.New("use of vendored package not allowed"),1669 }1670 return perr1671}16721673// FindVendor looks for the last non-terminating "vendor" path element in the given import path.1674// If there isn't one, FindVendor returns ok=false.1675// Otherwise, FindVendor returns ok=true and the index of the "vendor".1676//1677// Note that terminating "vendor" elements don't count: "x/vendor" is its own package,1678// not the vendored copy of an import "" (the empty import path).1679// This will allow people to have packages or commands named vendor.1680// This may help reduce breakage, or it may just be confusing. We'll see.1681func FindVendor(path string) (index int, ok bool) {1682 // Two cases, depending on internal at start of string or not.1683 // The order matters: we must return the index of the final element,1684 // because the final one is where the effective import path starts.1685 switch {1686 case strings.Contains(path, "/vendor/"):1687 return strings.LastIndex(path, "/vendor/") + 1, true1688 case strings.HasPrefix(path, "vendor/"):1689 return 0, true1690 }1691 return 0, false1692}16931694type TargetDir int16951696const (1697 ToTool TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*)1698 ToBin // to bin dir inside package root (default for non-cmd/*)1699)17001701// InstallTargetDir reports the target directory for installing the command p.1702func InstallTargetDir(p *Package) TargetDir {1703 if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" {1704 switch p.ImportPath {1705 case "cmd/go", "cmd/gofmt":1706 return ToBin1707 }1708 return ToTool1709 }1710 return ToBin1711}17121713var cgoExclude = map[string]bool{1714 "runtime/cgo": true,1715}17161717var cgoSyscallExclude = map[string]bool{1718 "runtime/cgo": true,1719 "runtime/race": true,1720 "runtime/msan": true,1721 "runtime/asan": true,1722}17231724var foldPath = make(map[string]string)17251726// exeFromImportPath returns an executable name1727// for a package using the import path.1728//1729// The executable name is the last element of the import path.1730// In module-aware mode, an additional rule is used on import paths1731// consisting of two or more path elements. If the last element is1732// a vN path element specifying the major version, then the1733// second last element of the import path is used instead.1734func (p *Package) exeFromImportPath() string {1735 _, elem := pathpkg.Split(p.ImportPath)1736 if cfg.ModulesEnabled {1737 // If this is example.com/mycmd/v2, it's more useful to1738 // install it as mycmd than as v2. See golang.org/issue/24667.1739 if elem != p.ImportPath && isVersionElement(elem) {1740 _, elem = pathpkg.Split(pathpkg.Dir(p.ImportPath))1741 }1742 }1743 return elem1744}17451746// exeFromFiles returns an executable name for a package1747// using the first element in GoFiles or CgoFiles collections without the prefix.1748//1749// Returns empty string in case of empty collection.1750func (p *Package) exeFromFiles() string {1751 var src string1752 if len(p.GoFiles) > 0 {1753 src = p.GoFiles[0]1754 } else if len(p.CgoFiles) > 0 {1755 src = p.CgoFiles[0]1756 } else {1757 return ""1758 }1759 _, elem := filepath.Split(src)1760 return elem[:len(elem)-len(".go")]1761}17621763// DefaultExecName returns the default executable name for a package1764func (p *Package) DefaultExecName() string {1765 if p.Internal.CmdlineFiles {1766 return p.exeFromFiles()1767 }1768 return p.exeFromImportPath()1769}17701771// The package used for rewriting "simd"1772const SimdBridgePkg = "simd/internal/bridge"17731774// hasSimd encodes the conditions under which the presence/absence of1775// imports of "simd" is interesting, i.e., if there is intrinsic1776// support, and hence some rewriting of AST to use the intrinsics.1777// This is used for both build and test (and perhaps in other contexts to1778// be discovered later).1779func hasSimd(imports []string) (hasSimd bool) {1780 if cfg.BuildContext.GOARCH == "wasm" || cfg.BuildContext.GOARCH == "amd64" || cfg.BuildContext.GOARCH == "arm64" {1781 for _, imp := range imports {1782 if imp == "simd" {1783 hasSimd = true1784 }1785 }1786 }1787 return1788}17891790// load populates p using information from bp, err, which should1791// be the result of calling build.Context.Import.1792// stk contains the import stack, not including path itself.1793func (p *Package) load(ld *modload.Loader, ctx context.Context, opts PackageOpts, path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) {1794 p.copyBuild(opts, bp)17951796 // The localPrefix is the path we interpret ./ imports relative to,1797 // if we support them at all (not in module mode!).1798 // Synthesized main packages sometimes override this.1799 if p.Internal.Local && !cfg.ModulesEnabled {1800 p.Internal.LocalPrefix = dirToImportPath(p.Dir)1801 }18021803 // setError sets p.Error if it hasn't already been set. We may proceed1804 // after encountering some errors so that 'go list -e' has more complete1805 // output. If there's more than one error, we should report the first.1806 setError := func(err error) {1807 if p.Error == nil {1808 p.Error = &PackageError{1809 ImportStack: stk.Copy(),1810 Err: err,1811 }1812 p.Incomplete = true18131814 // Add the importer's position information if the import position exists, and1815 // the current package being examined is the importer.1816 // If we have not yet accepted package p onto the import stack,1817 // then the cause of the error is not within p itself: the error1818 // must be either in an explicit command-line argument,1819 // or on the importer side (indicated by a non-empty importPos).1820 top, ok := stk.Top()1821 if ok && path != top.Pkg && len(importPos) > 0 {1822 p.Error.setPos(importPos)1823 }1824 }1825 }18261827 if err != nil {1828 p.Incomplete = true1829 p.setLoadPackageDataError(err, path, stk, importPos)1830 }18311832 useBindir := p.Name == "main"1833 if !p.Standard {1834 switch cfg.BuildBuildmode {1835 case "c-archive", "c-shared", "plugin":1836 useBindir = false1837 }1838 }18391840 if useBindir {1841 elem := p.DefaultExecName() + cfg.ExeSuffix1842 full := filepath.Join(cfg.BuildContext.GOOS+"_"+cfg.BuildContext.GOARCH, elem)1843 if cfg.BuildContext.GOOS != runtime.GOOS || cfg.BuildContext.GOARCH != runtime.GOARCH {1844 // Install cross-compiled binaries to subdirectories of bin.1845 elem = full1846 }1847 if p.Internal.Build.BinDir == "" && cfg.ModulesEnabled {1848 p.Internal.Build.BinDir = modload.BinDir(ld)1849 }1850 if p.Internal.Build.BinDir != "" {1851 // Install to GOBIN or bin of GOPATH entry.1852 p.Target = filepath.Join(p.Internal.Build.BinDir, elem)1853 if !p.Goroot && strings.Contains(elem, string(filepath.Separator)) && cfg.GOBIN != "" {1854 // Do not create $GOBIN/goos_goarch/elem.1855 p.Target = ""1856 p.Internal.GobinSubdir = true1857 }1858 }1859 if InstallTargetDir(p) == ToTool {1860 // This is for 'go tool'.1861 // Override all the usual logic and force it into the tool directory.1862 if cfg.BuildToolchainName == "gccgo" {1863 p.Target = filepath.Join(build.ToolDir, elem)1864 } else {1865 p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full)1866 }1867 }1868 } else if p.Internal.Local {1869 // Local import turned into absolute path.1870 // No permanent install target.1871 p.Target = ""1872 } else if p.Standard && cfg.BuildContext.Compiler == "gccgo" {1873 // gccgo has a preinstalled standard library that cmd/go cannot rebuild.1874 p.Target = ""1875 } else {1876 p.Target = p.Internal.Build.PkgObj1877 if cfg.BuildBuildmode == "shared" && p.Internal.Build.PkgTargetRoot != "" {1878 // TODO(matloob): This shouldn't be necessary, but the cmd/cgo/internal/testshared1879 // test fails without Target set for this condition. Figure out why and1880 // fix it.1881 p.Target = filepath.Join(p.Internal.Build.PkgTargetRoot, p.ImportPath+".a")1882 }1883 if cfg.BuildLinkshared && p.Internal.Build.PkgTargetRoot != "" {1884 // TODO(bcmills): The reliance on PkgTargetRoot implies that -linkshared does1885 // not work for any package that lacks a PkgTargetRoot — such as a non-main1886 // package in module mode. We should probably fix that.1887 targetPrefix := filepath.Join(p.Internal.Build.PkgTargetRoot, p.ImportPath)1888 p.Target = targetPrefix + ".a"1889 shlibnamefile := targetPrefix + ".shlibname"1890 shlib, err := os.ReadFile(shlibnamefile)1891 if err != nil && !os.IsNotExist(err) {1892 base.Fatalf("reading shlibname: %v", err)1893 }1894 if err == nil {1895 libname := strings.TrimSpace(string(shlib))1896 if cfg.BuildContext.Compiler == "gccgo" {1897 p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname)1898 } else {1899 p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname)1900 }1901 }1902 }1903 }19041905 // Build augmented import list to add implicit dependencies.1906 // Be careful not to add imports twice, just to avoid confusion.1907 importPaths := p.Imports1908 addImport := func(path string, forCompiler bool) {1909 for _, p := range importPaths {1910 if path == p {1911 return1912 }1913 }1914 importPaths = append(importPaths, path)1915 if forCompiler {1916 p.Internal.CompiledImports = append(p.Internal.CompiledImports, path)1917 }1918 }19191920 allowInternalSimdImport := 01921 if hasSimd := hasSimd(p.Imports); hasSimd {1922 addImport(SimdBridgePkg, true)1923 allowInternalSimdImport = allowSimdInternalBridge1924 }19251926 if !opts.IgnoreImports {1927 // Cgo translation adds imports of "unsafe", "runtime/cgo" and "syscall",1928 // except for certain packages, to avoid circular dependencies.1929 if p.UsesCgo() {1930 addImport("unsafe", true)1931 }1932 if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" {1933 addImport("runtime/cgo", true)1934 }1935 if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {1936 addImport("syscall", true)1937 }19381939 // SWIG adds imports of some standard packages.1940 if p.UsesSwig() {1941 addImport("unsafe", true)1942 if cfg.BuildContext.Compiler != "gccgo" {1943 addImport("runtime/cgo", true)1944 }1945 addImport("syscall", true)1946 addImport("sync", true)19471948 // TODO: The .swig and .swigcxx files can use1949 // %go_import directives to import other packages.1950 }19511952 // The linker loads implicit dependencies.1953 if p.Name == "main" && !p.Internal.ForceLibrary {1954 ldDeps, err := LinkerDeps(ld, p)1955 if err != nil {1956 setError(err)1957 return1958 }1959 for _, dep := range ldDeps {1960 addImport(dep, false)1961 }1962 }1963 }19641965 // Check for case-insensitive collisions of import paths.1966 // If modifying, consider changing checkPathCollisions() in1967 // src/cmd/go/internal/modcmd/vendor.go1968 fold := str.ToFold(p.ImportPath)1969 if other := foldPath[fold]; other == "" {1970 foldPath[fold] = p.ImportPath1971 } else if other != p.ImportPath {1972 setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other))1973 return1974 }19751976 if !SafeArg(p.ImportPath) {1977 setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath))1978 return1979 }19801981 // Errors after this point are caused by this package, not the importing1982 // package. Pushing the path here prevents us from reporting the error1983 // with the position of the import declaration.1984 stk.Push(ImportInfo{Pkg: path, Pos: extractFirstImport(importPos)})1985 defer stk.Pop()19861987 if p.BinaryOnly {1988 setError(errors.New("binary-only packages are no longer supported"))1989 }19901991 pkgPath := p.ImportPath1992 if p.Internal.CmdlineFiles {1993 pkgPath = "command-line-arguments"1994 }1995 if cfg.ModulesEnabled {1996 p.Module = modload.PackageModuleInfo(ld, ctx, pkgPath)1997 }1998 p.DefaultGODEBUG = defaultGODEBUG(ld, p, nil, nil, nil)19992000 if !opts.SuppressEmbedFiles {
Findings
✓ No findings reported for this file.