Skip to content

Commit 2904639

Browse files
committed
cmd/go: refactor injection of modload.LoaderState
This change refactors the injection of the global `modload.LoaderState` variable such that the injection can occur later in the chain of function calls. This allows us to keep the behavior of the global PerPackageFlags (e.g. BuildGcFlags, etc) consistent and avoid introducing a dependency on the module loader state there. This commit is part of the overall effort to eliminate global modloader state. Change-Id: I1a0cc07173a1804426392581ba8de4ae1e30cdef Reviewed-on: https://go-review.googlesource.com/c/go/+/711115 Reviewed-by: Michael Matloob <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Michael Matloob <[email protected]>
1 parent c18fa69 commit 2904639

File tree

7 files changed

+85
-81
lines changed

7 files changed

+85
-81
lines changed

src/cmd/go/internal/load/flag.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ type PerPackageFlag struct {
3030

3131
// A ppfValue is a single <pattern>=<flags> per-package flag value.
3232
type ppfValue struct {
33-
match func(*Package) bool // compiled pattern
33+
match func(*modload.State, *Package) bool // compiled pattern
3434
flags []string
3535
}
3636

@@ -43,7 +43,7 @@ func (f *PerPackageFlag) Set(v string) error {
4343
func (f *PerPackageFlag) set(v, cwd string) error {
4444
f.raw = v
4545
f.present = true
46-
match := func(p *Package) bool { return p.Internal.CmdlinePkg || p.Internal.CmdlineFiles } // default predicate with no pattern
46+
match := func(_ *modload.State, p *Package) bool { return p.Internal.CmdlinePkg || p.Internal.CmdlineFiles } // default predicate with no pattern
4747
// For backwards compatibility with earlier flag splitting, ignore spaces around flags.
4848
v = strings.TrimSpace(v)
4949
if v == "" {
@@ -64,7 +64,7 @@ func (f *PerPackageFlag) set(v, cwd string) error {
6464
return fmt.Errorf("parameter may not start with quote character %c", v[0])
6565
}
6666
pattern := strings.TrimSpace(v[:i])
67-
match = MatchPackage(modload.LoaderState, pattern, cwd)
67+
match = MatchPackage(pattern, cwd)
6868
v = v[i+1:]
6969
}
7070
flags, err := quoted.Split(v)
@@ -86,10 +86,13 @@ func (f *PerPackageFlag) Present() bool {
8686
}
8787

8888
// For returns the flags to use for the given package.
89-
func (f *PerPackageFlag) For(p *Package) []string {
89+
//
90+
// The module loader state is used by the matcher to know if certain
91+
// patterns match packages within the state's MainModules.
92+
func (f *PerPackageFlag) For(s *modload.State, p *Package) []string {
9093
flags := []string{}
9194
for _, v := range f.values {
92-
if v.match(p) {
95+
if v.match(s, p) {
9396
flags = v.flags
9497
}
9598
}

src/cmd/go/internal/load/flag_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package load
66

77
import (
8+
"cmd/go/internal/modload"
89
"fmt"
910
"path/filepath"
1011
"reflect"
@@ -125,7 +126,7 @@ func TestPerPackageFlag(t *testing.T) {
125126
}
126127
for _, p := range tt.pkgs {
127128
dir := nativeDir(p.dir)
128-
flags := ppFlags.For(&Package{PackagePublic: PackagePublic{ImportPath: p.path, Dir: dir}, Internal: PackageInternal{CmdlinePkg: p.cmdline}})
129+
flags := ppFlags.For(modload.NewState(), &Package{PackagePublic: PackagePublic{ImportPath: p.path, Dir: dir}, Internal: PackageInternal{CmdlinePkg: p.cmdline}})
129130
if !reflect.DeepEqual(flags, p.flags) {
130131
t.Errorf("For(%v, %v, %v) = %v, want %v", p.path, dir, p.cmdline, flags, p.flags)
131132
}

src/cmd/go/internal/load/pkg.go

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -355,14 +355,14 @@ func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportSta
355355
// can produce better error messages if it starts with the original paths.
356356
// The initial load of p loads all the non-test imports and rewrites
357357
// the vendored paths, so nothing should ever call p.vendored(p.Imports).
358-
func (p *Package) Resolve(loaderstate *modload.State, imports []string) []string {
358+
func (p *Package) Resolve(s *modload.State, imports []string) []string {
359359
if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] {
360360
panic("internal error: p.Resolve(p.Imports) called")
361361
}
362362
seen := make(map[string]bool)
363363
var all []string
364364
for _, path := range imports {
365-
path = ResolveImportPath(loaderstate, p, path)
365+
path = ResolveImportPath(s, p, path)
366366
if !seen[path] {
367367
seen[path] = true
368368
all = append(all, path)
@@ -1151,7 +1151,7 @@ func isDir(path string) bool {
11511151
// First, there is Go 1.5 vendoring (golang.org/s/go15vendor).
11521152
// If vendor expansion doesn't trigger, then the path is also subject to
11531153
// Go 1.11 module legacy conversion (golang.org/issue/25069).
1154-
func ResolveImportPath(loaderstate *modload.State, parent *Package, path string) (found string) {
1154+
func ResolveImportPath(s *modload.State, parent *Package, path string) (found string) {
11551155
var parentPath, parentDir, parentRoot string
11561156
parentIsStd := false
11571157
if parent != nil {
@@ -1160,12 +1160,12 @@ func ResolveImportPath(loaderstate *modload.State, parent *Package, path string)
11601160
parentRoot = parent.Root
11611161
parentIsStd = parent.Standard
11621162
}
1163-
return resolveImportPath(loaderstate, path, parentPath, parentDir, parentRoot, parentIsStd)
1163+
return resolveImportPath(s, path, parentPath, parentDir, parentRoot, parentIsStd)
11641164
}
11651165

1166-
func resolveImportPath(loaderstate *modload.State, path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) {
1166+
func resolveImportPath(s *modload.State, path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) {
11671167
if cfg.ModulesEnabled {
1168-
if _, p, e := modload.Lookup(loaderstate, parentPath, parentIsStd, path); e == nil {
1168+
if _, p, e := modload.Lookup(s, parentPath, parentIsStd, path); e == nil {
11691169
return p
11701170
}
11711171
return path
@@ -1935,7 +1935,7 @@ func (p *Package) load(loaderstate *modload.State, ctx context.Context, opts Pac
19351935

19361936
// The linker loads implicit dependencies.
19371937
if p.Name == "main" && !p.Internal.ForceLibrary {
1938-
ldDeps, err := LinkerDeps(p)
1938+
ldDeps, err := LinkerDeps(loaderstate, p)
19391939
if err != nil {
19401940
setError(err)
19411941
return
@@ -2635,12 +2635,12 @@ func SafeArg(name string) bool {
26352635
}
26362636

26372637
// LinkerDeps returns the list of linker-induced dependencies for main package p.
2638-
func LinkerDeps(p *Package) ([]string, error) {
2638+
func LinkerDeps(s *modload.State, p *Package) ([]string, error) {
26392639
// Everything links runtime.
26402640
deps := []string{"runtime"}
26412641

26422642
// External linking mode forces an import of runtime/cgo.
2643-
if what := externalLinkingReason(p); what != "" && cfg.BuildContext.Compiler != "gccgo" {
2643+
if what := externalLinkingReason(s, p); what != "" && cfg.BuildContext.Compiler != "gccgo" {
26442644
if !cfg.BuildContext.CgoEnabled {
26452645
return nil, fmt.Errorf("%s requires external (cgo) linking, but cgo is not enabled", what)
26462646
}
@@ -2673,7 +2673,7 @@ func LinkerDeps(p *Package) ([]string, error) {
26732673
// externalLinkingReason reports the reason external linking is required
26742674
// even for programs that do not use cgo, or the empty string if external
26752675
// linking is not required.
2676-
func externalLinkingReason(p *Package) (what string) {
2676+
func externalLinkingReason(s *modload.State, p *Package) (what string) {
26772677
// Some targets must use external linking even inside GOROOT.
26782678
if platform.MustLinkExternal(cfg.Goos, cfg.Goarch, false) {
26792679
return cfg.Goos + "/" + cfg.Goarch
@@ -2716,7 +2716,7 @@ func externalLinkingReason(p *Package) (what string) {
27162716
// Using -ldflags=-linkmode=external forces external linking.
27172717
// If there are multiple -linkmode options, the last one wins.
27182718
if p != nil {
2719-
ldflags := BuildLdflags.For(p)
2719+
ldflags := BuildLdflags.For(s, p)
27202720
for i := len(ldflags) - 1; i >= 0; i-- {
27212721
a := ldflags[i]
27222722
if a == "-linkmode=external" ||
@@ -2842,15 +2842,15 @@ func TestPackageList(loaderstate *modload.State, ctx context.Context, opts Packa
28422842
// in LoadImport instead.
28432843
func LoadImportWithFlags(loaderstate *modload.State, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) (*Package, *PackageError) {
28442844
p, err := loadImport(loaderstate, context.TODO(), PackageOpts{}, nil, path, srcDir, parent, stk, importPos, mode)
2845-
setToolFlags(p)
2845+
setToolFlags(loaderstate, p)
28462846
return p, err
28472847
}
28482848

28492849
// LoadPackageWithFlags is the same as LoadImportWithFlags but without a parent.
28502850
// It's then guaranteed to not return an error
28512851
func LoadPackageWithFlags(loaderstate *modload.State, path, srcDir string, stk *ImportStack, importPos []token.Position, mode int) *Package {
28522852
p := LoadPackage(loaderstate, context.TODO(), PackageOpts{}, path, srcDir, stk, importPos, mode)
2853-
setToolFlags(p)
2853+
setToolFlags(loaderstate, p)
28542854
return p
28552855
}
28562856

@@ -2992,7 +2992,7 @@ func PackagesAndErrors(loaderstate *modload.State, ctx context.Context, opts Pac
29922992
// compute the effective flags for all loaded packages
29932993
// (not just the ones matching the patterns but also
29942994
// their dependencies).
2995-
setToolFlags(pkgs...)
2995+
setToolFlags(loaderstate, pkgs...)
29962996

29972997
setPGOProfilePath(pkgs)
29982998

@@ -3231,12 +3231,12 @@ func (e *mainPackageError) ImportPath() string {
32313231
return e.importPath
32323232
}
32333233

3234-
func setToolFlags(pkgs ...*Package) {
3234+
func setToolFlags(loaderstate *modload.State, pkgs ...*Package) {
32353235
for _, p := range PackageList(pkgs) {
3236-
p.Internal.Asmflags = BuildAsmflags.For(p)
3237-
p.Internal.Gcflags = BuildGcflags.For(p)
3238-
p.Internal.Ldflags = BuildLdflags.For(p)
3239-
p.Internal.Gccgoflags = BuildGccgoflags.For(p)
3236+
p.Internal.Asmflags = BuildAsmflags.For(loaderstate, p)
3237+
p.Internal.Gcflags = BuildGcflags.For(loaderstate, p)
3238+
p.Internal.Ldflags = BuildLdflags.For(loaderstate, p)
3239+
p.Internal.Gccgoflags = BuildGccgoflags.For(loaderstate, p)
32403240
}
32413241
}
32423242

@@ -3327,7 +3327,7 @@ func GoFilesPackage(loaderstate *modload.State, ctx context.Context, opts Packag
33273327
pkg.Error = &PackageError{Err: &mainPackageError{importPath: pkg.ImportPath}}
33283328
pkg.Incomplete = true
33293329
}
3330-
setToolFlags(pkg)
3330+
setToolFlags(loaderstate, pkg)
33313331

33323332
return pkg
33333333
}
@@ -3471,14 +3471,14 @@ func PackagesAndErrorsOutsideModule(loaderstate *modload.State, ctx context.Cont
34713471
}
34723472

34733473
// EnsureImport ensures that package p imports the named package.
3474-
func EnsureImport(loaderstate *modload.State, p *Package, pkg string) {
3474+
func EnsureImport(s *modload.State, p *Package, pkg string) {
34753475
for _, d := range p.Internal.Imports {
34763476
if d.Name == pkg {
34773477
return
34783478
}
34793479
}
34803480

3481-
p1, err := LoadImportWithFlags(loaderstate, pkg, p.Dir, p, &ImportStack{}, nil, 0)
3481+
p1, err := LoadImportWithFlags(s, pkg, p.Dir, p, &ImportStack{}, nil, 0)
34823482
if err != nil {
34833483
base.Fatalf("load %s: %v", pkg, err)
34843484
}
@@ -3494,35 +3494,35 @@ func EnsureImport(loaderstate *modload.State, p *Package, pkg string) {
34943494
// "go test -cover"). It walks through the packages being built (and
34953495
// dependencies) and marks them for coverage instrumentation when
34963496
// appropriate, and possibly adding additional deps where needed.
3497-
func PrepareForCoverageBuild(loaderstate *modload.State, pkgs []*Package) {
3498-
var match []func(*Package) bool
3497+
func PrepareForCoverageBuild(s *modload.State, pkgs []*Package) {
3498+
var match []func(*modload.State, *Package) bool
34993499

3500-
matchMainModAndCommandLine := func(p *Package) bool {
3500+
matchMainModAndCommandLine := func(_ *modload.State, p *Package) bool {
35013501
// note that p.Standard implies p.Module == nil below.
35023502
return p.Internal.CmdlineFiles || p.Internal.CmdlinePkg || (p.Module != nil && p.Module.Main)
35033503
}
35043504

35053505
if len(cfg.BuildCoverPkg) != 0 {
35063506
// If -coverpkg has been specified, then we instrument only
35073507
// the specific packages selected by the user-specified pattern(s).
3508-
match = make([]func(*Package) bool, len(cfg.BuildCoverPkg))
3508+
match = make([]func(*modload.State, *Package) bool, len(cfg.BuildCoverPkg))
35093509
for i := range cfg.BuildCoverPkg {
3510-
match[i] = MatchPackage(loaderstate, cfg.BuildCoverPkg[i], base.Cwd())
3510+
match[i] = MatchPackage(cfg.BuildCoverPkg[i], base.Cwd())
35113511
}
35123512
} else {
35133513
// Without -coverpkg, instrument only packages in the main module
35143514
// (if any), as well as packages/files specifically named on the
35153515
// command line.
3516-
match = []func(*Package) bool{matchMainModAndCommandLine}
3516+
match = []func(*modload.State, *Package) bool{matchMainModAndCommandLine}
35173517
}
35183518

35193519
// Visit the packages being built or installed, along with all of
35203520
// their dependencies, and mark them to be instrumented, taking
35213521
// into account the matchers we've set up in the sequence above.
3522-
SelectCoverPackages(loaderstate, PackageList(pkgs), match, "build")
3522+
SelectCoverPackages(s, PackageList(pkgs), match, "build")
35233523
}
35243524

3525-
func SelectCoverPackages(loaderstate *modload.State, roots []*Package, match []func(*Package) bool, op string) []*Package {
3525+
func SelectCoverPackages(s *modload.State, roots []*Package, match []func(*modload.State, *Package) bool, op string) []*Package {
35263526
var warntag string
35273527
var includeMain bool
35283528
switch op {
@@ -3540,7 +3540,7 @@ func SelectCoverPackages(loaderstate *modload.State, roots []*Package, match []f
35403540
for _, p := range roots {
35413541
haveMatch := false
35423542
for i := range match {
3543-
if match[i](p) {
3543+
if match[i](s, p) {
35443544
matched[i] = true
35453545
haveMatch = true
35463546
}
@@ -3602,7 +3602,7 @@ func SelectCoverPackages(loaderstate *modload.State, roots []*Package, match []f
36023602

36033603
// Force import of sync/atomic into package if atomic mode.
36043604
if cfg.BuildCoverMode == "atomic" {
3605-
EnsureImport(loaderstate, p, "sync/atomic")
3605+
EnsureImport(s, p, "sync/atomic")
36063606
}
36073607
}
36083608

src/cmd/go/internal/load/search.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
)
1515

1616
// MatchPackage(pattern, cwd)(p) reports whether package p matches pattern in the working directory cwd.
17-
func MatchPackage(loaderstate *modload.State, pattern, cwd string) func(*Package) bool {
17+
func MatchPackage(pattern, cwd string) func(*modload.State, *Package) bool {
1818
switch {
1919
case search.IsRelativePath(pattern):
2020
// Split pattern into leading pattern-free directory path
@@ -29,10 +29,10 @@ func MatchPackage(loaderstate *modload.State, pattern, cwd string) func(*Package
2929
}
3030
dir = filepath.Join(cwd, dir)
3131
if pattern == "" {
32-
return func(p *Package) bool { return p.Dir == dir }
32+
return func(_ *modload.State, p *Package) bool { return p.Dir == dir }
3333
}
3434
matchPath := pkgpattern.MatchPattern(pattern)
35-
return func(p *Package) bool {
35+
return func(_ *modload.State, p *Package) bool {
3636
// Compute relative path to dir and see if it matches the pattern.
3737
rel, err := filepath.Rel(dir, p.Dir)
3838
if err != nil {
@@ -49,22 +49,22 @@ func MatchPackage(loaderstate *modload.State, pattern, cwd string) func(*Package
4949
// This is slightly inaccurate: it matches every package, which isn't the same
5050
// as matching the "all" package pattern.
5151
// TODO(matloob): Should we make this more accurate? Does anyone depend on this behavior?
52-
return func(p *Package) bool { return true }
52+
return func(_ *modload.State, p *Package) bool { return true }
5353
case pattern == "std":
54-
return func(p *Package) bool { return p.Standard }
54+
return func(_ *modload.State, p *Package) bool { return p.Standard }
5555
case pattern == "cmd":
56-
return func(p *Package) bool { return p.Standard && strings.HasPrefix(p.ImportPath, "cmd/") }
57-
case pattern == "tool" && modload.Enabled(loaderstate):
58-
return func(p *Package) bool {
59-
return loaderstate.MainModules.Tools()[p.ImportPath]
60-
}
61-
case pattern == "work" && modload.Enabled(loaderstate):
62-
return func(p *Package) bool {
63-
return p.Module != nil && loaderstate.MainModules.Contains(p.Module.Path)
64-
}
65-
56+
return func(_ *modload.State, p *Package) bool { return p.Standard && strings.HasPrefix(p.ImportPath, "cmd/") }
6657
default:
67-
matchPath := pkgpattern.MatchPattern(pattern)
68-
return func(p *Package) bool { return matchPath(p.ImportPath) }
58+
return func(s *modload.State, p *Package) bool {
59+
switch {
60+
case pattern == "tool" && modload.Enabled(s):
61+
return s.MainModules.Tools()[p.ImportPath]
62+
case pattern == "work" && modload.Enabled(s):
63+
return p.Module != nil && s.MainModules.Contains(p.Module.Path)
64+
default:
65+
matchPath := pkgpattern.MatchPattern(pattern)
66+
return matchPath(p.ImportPath)
67+
}
68+
}
6969
}
7070
}

src/cmd/go/internal/load/test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ func TestPackagesAndErrors(loaderstate *modload.State, ctx context.Context, done
311311
if cover != nil {
312312
deps = append(deps, "internal/coverage/cfile")
313313
}
314-
ldDeps, err := LinkerDeps(p)
314+
ldDeps, err := LinkerDeps(loaderstate, p)
315315
if err != nil && pmain.Error == nil {
316316
pmain.Error = &PackageError{Err: err}
317317
}
@@ -337,7 +337,7 @@ func TestPackagesAndErrors(loaderstate *modload.State, ctx context.Context, done
337337
allTestImports = append(allTestImports, pmain.Internal.Imports...)
338338
allTestImports = append(allTestImports, imports...)
339339
allTestImports = append(allTestImports, ximports...)
340-
setToolFlags(allTestImports...)
340+
setToolFlags(loaderstate, allTestImports...)
341341

342342
// Do initial scan for metadata needed for writing _testmain.go
343343
// Use that metadata to update the list of imports for package main.

src/cmd/go/internal/test/test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -865,9 +865,9 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
865865
var writeCoverMetaAct *work.Action
866866

867867
if cfg.BuildCoverPkg != nil {
868-
match := make([]func(*load.Package) bool, len(cfg.BuildCoverPkg))
868+
match := make([]func(*modload.State, *load.Package) bool, len(cfg.BuildCoverPkg))
869869
for i := range cfg.BuildCoverPkg {
870-
match[i] = load.MatchPackage(modload.LoaderState, cfg.BuildCoverPkg[i], base.Cwd())
870+
match[i] = load.MatchPackage(cfg.BuildCoverPkg[i], base.Cwd())
871871
}
872872

873873
// Select for coverage all dependencies matching the -coverpkg

0 commit comments

Comments
 (0)