aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/load/pkg.go
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2021-03-03 10:27:19 -0500
committerBryan C. Mills <bcmills@google.com>2021-03-25 03:17:36 +0000
commit954879d6d19175a5f0066c0ac0df0edda7f731b3 (patch)
tree891e4d63c5fa5cd41bbb957d6030d4e910105151 /src/cmd/go/internal/load/pkg.go
parenta95e2ae2804becdda6c265c6d589ae8184a34160 (diff)
downloadgo-954879d6d19175a5f0066c0ac0df0edda7f731b3.tar.gz
go-954879d6d19175a5f0066c0ac0df0edda7f731b3.zip
cmd/go/internal/modload: replace the global buildList with structured requirements
This is intended to be a pure-refactoring change, with very little observable change in the behavior of the 'go' command. A few error messages have prefixes changed (by virtue of being attached to packages or modules instead of the build list overall), and 'go list -m' (without arguments) no longer loads the complete module graph in order to provide the name of the (local) main module. The previous modload.buildList variable contained a flattened build list, from which the go.mod file was reconstructed using various heuristics and metadata cobbled together from the original go.mod file, the package loader (which was occasionally constructed without actually loading packages, for the sole purpose of populating otherwise-unrelated metadata!), and the updated build list. This change replaces that variable with a new package-level variable, named "requirements". The new variable is structured to match the structure of the go.mod file: it explicitly specifies the roots of the module graph, from which the complete module graph and complete build list can be reconstructed (and cached) on demand. Similarly, the "direct" markings on the go.mod requirements are now stored alongside the requirements themselves, rather than side-channeled through the loader. The requirements are now plumbed explicitly though the modload package, with accesses to the package-level variable occurring only within top-level exported functions. The structured requirements are logically immutable, so a new copy of the requirements is constructed whenever the requirements are changed, substantially reducing implicit communication-by-sharing in the package. For #36460 Updates #40775 Change-Id: I97bb0381708f9d3e42af385b5c88a7038e1f0556 Reviewed-on: https://go-review.googlesource.com/c/go/+/293689 Trust: Bryan C. Mills <bcmills@google.com> Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Matloob <matloob@golang.org>
Diffstat (limited to 'src/cmd/go/internal/load/pkg.go')
-rw-r--r--src/cmd/go/internal/load/pkg.go30
1 files changed, 15 insertions, 15 deletions
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 61fde895f8..c9619f1b28 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -665,9 +665,9 @@ func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *
parentRoot = parent.Root
parentIsStd = parent.Standard
}
- bp, loaded, err := loadPackageData(path, parentPath, srcDir, parentRoot, parentIsStd, mode)
+ bp, loaded, err := loadPackageData(ctx, path, parentPath, srcDir, parentRoot, parentIsStd, mode)
if loaded && pre != nil && !IgnoreImports {
- pre.preloadImports(bp.Imports, bp)
+ pre.preloadImports(ctx, bp.Imports, bp)
}
if bp == nil {
if importErr, ok := err.(ImportPathError); !ok || importErr.ImportPath() != path {
@@ -714,7 +714,7 @@ func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *
}
// Checked on every import because the rules depend on the code doing the importing.
- if perr := disallowInternal(srcDir, parent, parentPath, p, stk); perr != p {
+ if perr := disallowInternal(ctx, srcDir, parent, parentPath, p, stk); perr != p {
perr.Error.setPos(importPos)
return perr
}
@@ -763,7 +763,7 @@ func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *
//
// loadPackageData returns a boolean, loaded, which is true if this is the
// first time the package was loaded. Callers may preload imports in this case.
-func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd bool, mode int) (bp *build.Package, loaded bool, err error) {
+func loadPackageData(ctx context.Context, path, parentPath, parentDir, parentRoot string, parentIsStd bool, mode int) (bp *build.Package, loaded bool, err error) {
if path == "" {
panic("loadPackageData called with empty package path")
}
@@ -836,7 +836,7 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd
}
data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode)
if data.p.Root == "" && cfg.ModulesEnabled {
- if info := modload.PackageModuleInfo(path); info != nil {
+ if info := modload.PackageModuleInfo(ctx, path); info != nil {
data.p.Root = info.Dir
}
}
@@ -950,7 +950,7 @@ func newPreload() *preload {
// preloadMatches loads data for package paths matched by patterns.
// When preloadMatches returns, some packages may not be loaded yet, but
// loadPackageData and loadImport are always safe to call.
-func (pre *preload) preloadMatches(matches []*search.Match) {
+func (pre *preload) preloadMatches(ctx context.Context, matches []*search.Match) {
for _, m := range matches {
for _, pkg := range m.Pkgs {
select {
@@ -959,10 +959,10 @@ func (pre *preload) preloadMatches(matches []*search.Match) {
case pre.sema <- struct{}{}:
go func(pkg string) {
mode := 0 // don't use vendoring or module import resolution
- bp, loaded, err := loadPackageData(pkg, "", base.Cwd, "", false, mode)
+ bp, loaded, err := loadPackageData(ctx, pkg, "", base.Cwd, "", false, mode)
<-pre.sema
if bp != nil && loaded && err == nil && !IgnoreImports {
- pre.preloadImports(bp.Imports, bp)
+ pre.preloadImports(ctx, bp.Imports, bp)
}
}(pkg)
}
@@ -973,7 +973,7 @@ func (pre *preload) preloadMatches(matches []*search.Match) {
// preloadImports queues a list of imports for preloading.
// When preloadImports returns, some packages may not be loaded yet,
// but loadPackageData and loadImport are always safe to call.
-func (pre *preload) preloadImports(imports []string, parent *build.Package) {
+func (pre *preload) preloadImports(ctx context.Context, imports []string, parent *build.Package) {
parentIsStd := parent.Goroot && parent.ImportPath != "" && search.IsStandardImportPath(parent.ImportPath)
for _, path := range imports {
if path == "C" || path == "unsafe" {
@@ -984,10 +984,10 @@ func (pre *preload) preloadImports(imports []string, parent *build.Package) {
return
case pre.sema <- struct{}{}:
go func(path string) {
- bp, loaded, err := loadPackageData(path, parent.ImportPath, parent.Dir, parent.Root, parentIsStd, ResolveImport)
+ bp, loaded, err := loadPackageData(ctx, path, parent.ImportPath, parent.Dir, parent.Root, parentIsStd, ResolveImport)
<-pre.sema
if bp != nil && loaded && err == nil && !IgnoreImports {
- pre.preloadImports(bp.Imports, bp)
+ pre.preloadImports(ctx, bp.Imports, bp)
}
}(path)
}
@@ -1343,7 +1343,7 @@ func reusePackage(p *Package, stk *ImportStack) *Package {
// is allowed to import p.
// If the import is allowed, disallowInternal returns the original package p.
// If not, it returns a new package containing just an appropriate error.
-func disallowInternal(srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *Package {
+func disallowInternal(ctx context.Context, srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *Package {
// golang.org/s/go14internal:
// An import of a path containing the element “internal”
// is disallowed if the importing code is outside the tree
@@ -1415,7 +1415,7 @@ func disallowInternal(srcDir string, importer *Package, importerPath string, p *
// directory containing them.
// If the directory is outside the main module, this will resolve to ".",
// which is not a prefix of any valid module.
- importerPath = modload.DirImportPath(importer.Dir)
+ importerPath = modload.DirImportPath(ctx, importer.Dir)
}
parentOfInternal := p.ImportPath[:i]
if str.HasPathPrefix(importerPath, parentOfInternal) {
@@ -1918,7 +1918,7 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor
if p.Internal.CmdlineFiles {
mainPath = "command-line-arguments"
}
- p.Module = modload.PackageModuleInfo(mainPath)
+ p.Module = modload.PackageModuleInfo(ctx, mainPath)
if p.Name == "main" && len(p.DepsErrors) == 0 {
p.Internal.BuildInfo = modload.PackageBuildInfo(mainPath, p.Deps)
}
@@ -2405,7 +2405,7 @@ func PackagesAndErrors(ctx context.Context, patterns []string) []*Package {
pre := newPreload()
defer pre.flush()
- pre.preloadMatches(matches)
+ pre.preloadMatches(ctx, matches)
for _, m := range matches {
for _, pkg := range m.Pkgs {