]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/cmd/go/internal/load/pkg.go
[dev.boringcrypto] all: merge commit 57c115e1 into dev.boringcrypto
[gostls13.git] / src / cmd / go / internal / load / pkg.go
index fa040bf5b11f643faf433a40a0954fd9a8c8cf19..f5f0f3539318af4b0d6ac7eb32cd7eac2702aabf 100644 (file)
@@ -36,8 +36,8 @@ import (
        "cmd/go/internal/modload"
        "cmd/go/internal/par"
        "cmd/go/internal/search"
-       "cmd/go/internal/str"
        "cmd/go/internal/trace"
+       "cmd/internal/str"
        "cmd/internal/sys"
 
        "golang.org/x/mod/modfile"
@@ -87,6 +87,7 @@ type PackagePublic struct {
        CgoFiles          []string `json:",omitempty"` // .go source files that import "C"
        CompiledGoFiles   []string `json:",omitempty"` // .go output from running cgo on CgoFiles
        IgnoredGoFiles    []string `json:",omitempty"` // .go source files ignored due to build constraints
+       InvalidGoFiles    []string `json:",omitempty"` // .go source files with detected problems (parse error, wrong package name, and so on)
        IgnoredOtherFiles []string `json:",omitempty"` // non-.go source files ignored due to build constraints
        CFiles            []string `json:",omitempty"` // .c source files
        CXXFiles          []string `json:",omitempty"` // .cc, .cpp and .cxx source files
@@ -144,6 +145,7 @@ func (p *Package) AllFiles() []string {
                p.CgoFiles,
                // no p.CompiledGoFiles, because they are from GoFiles or generated by us
                p.IgnoredGoFiles,
+               // no p.InvalidGoFiles, because they are from GoFiles
                p.IgnoredOtherFiles,
                p.CFiles,
                p.CXXFiles,
@@ -192,8 +194,8 @@ type PackageInternal struct {
        // Unexported fields are not part of the public API.
        Build             *build.Package
        Imports           []*Package           // this package's direct imports
-       CompiledImports   []string             // additional Imports necessary when using CompiledGoFiles (all from standard library)
-       RawImports        []string             // this package's original imports as they appear in the text of the program
+       CompiledImports   []string             // additional Imports necessary when using CompiledGoFiles (all from standard library); 1:1 with the end of PackagePublic.Imports
+       RawImports        []string             // this package's original imports as they appear in the text of the program; 1:1 with the end of PackagePublic.Imports
        ForceLibrary      bool                 // this package is a library (even if named "main")
        CmdlineFiles      bool                 // package built from files listed on command line
        CmdlinePkg        bool                 // package listed on command line
@@ -371,6 +373,7 @@ func (p *Package) copyBuild(opts PackageOpts, pp *build.Package) {
        p.GoFiles = pp.GoFiles
        p.CgoFiles = pp.CgoFiles
        p.IgnoredGoFiles = pp.IgnoredGoFiles
+       p.InvalidGoFiles = pp.InvalidGoFiles
        p.IgnoredOtherFiles = pp.IgnoredOtherFiles
        p.CFiles = pp.CFiles
        p.CXXFiles = pp.CXXFiles
@@ -852,7 +855,9 @@ func loadPackageData(ctx context.Context, path, parentPath, parentDir, parentRoo
                                buildMode = build.ImportComment
                        }
                        data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode)
-                       if data.p.Root == "" && cfg.ModulesEnabled {
+                       if cfg.ModulesEnabled {
+                               // Override data.p.Root, since ImportDir sets it to $GOPATH, if
+                               // the module is inside $GOPATH/src.
                                if info := modload.PackageModuleInfo(ctx, path); info != nil {
                                        data.p.Root = info.Dir
                                }
@@ -1800,35 +1805,37 @@ func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *
                }
        }
 
-       // Cgo translation adds imports of "unsafe", "runtime/cgo" and "syscall",
-       // except for certain packages, to avoid circular dependencies.
-       if p.UsesCgo() {
-               addImport("unsafe", true)
-       }
-       if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" {
-               addImport("runtime/cgo", true)
-       }
-       if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
-               addImport("syscall", true)
-       }
-
-       // SWIG adds imports of some standard packages.
-       if p.UsesSwig() {
-               addImport("unsafe", true)
-               if cfg.BuildContext.Compiler != "gccgo" {
+       if !opts.IgnoreImports {
+               // Cgo translation adds imports of "unsafe", "runtime/cgo" and "syscall",
+               // except for certain packages, to avoid circular dependencies.
+               if p.UsesCgo() {
+                       addImport("unsafe", true)
+               }
+               if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" {
                        addImport("runtime/cgo", true)
                }
-               addImport("syscall", true)
-               addImport("sync", true)
+               if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
+                       addImport("syscall", true)
+               }
 
-               // TODO: The .swig and .swigcxx files can use
-               // %go_import directives to import other packages.
-       }
+               // SWIG adds imports of some standard packages.
+               if p.UsesSwig() {
+                       addImport("unsafe", true)
+                       if cfg.BuildContext.Compiler != "gccgo" {
+                               addImport("runtime/cgo", true)
+                       }
+                       addImport("syscall", true)
+                       addImport("sync", true)
+
+                       // TODO: The .swig and .swigcxx files can use
+                       // %go_import directives to import other packages.
+               }
 
-       // The linker loads implicit dependencies.
-       if p.Name == "main" && !p.Internal.ForceLibrary {
-               for _, dep := range LinkerDeps(p) {
-                       addImport(dep, false)
+               // The linker loads implicit dependencies.
+               if p.Name == "main" && !p.Internal.ForceLibrary {
+                       for _, dep := range LinkerDeps(p) {
+                               addImport(dep, false)
+                       }
                }
        }
 
@@ -2390,7 +2397,9 @@ func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack,
 // PackageOpts control the behavior of PackagesAndErrors and other package
 // loading functions.
 type PackageOpts struct {
-       // IgnoreImports controls whether we ignore imports when loading packages.
+       // IgnoreImports controls whether we ignore explicit and implicit imports
+       // when loading packages.  Implicit imports are added when supporting Cgo
+       // or SWIG and when linking main packages.
        IgnoreImports bool
 
        // ModResolveTests indicates whether calls to the module loader should also
@@ -2499,7 +2508,7 @@ func PackagesAndErrors(ctx context.Context, opts PackageOpts, patterns []string)
        }
 
        if opts.MainOnly {
-               pkgs = mainPackagesOnly(pkgs, patterns)
+               pkgs = mainPackagesOnly(pkgs, matches)
        }
 
        // Now that CmdlinePkg is set correctly,
@@ -2553,50 +2562,63 @@ func CheckPackageErrors(pkgs []*Package) {
 // mainPackagesOnly filters out non-main packages matched only by arguments
 // containing "..." and returns the remaining main packages.
 //
+// Packages with missing, invalid, or ambiguous names may be treated as
+// possibly-main packages.
+//
 // mainPackagesOnly sets a non-main package's Error field and returns it if it
 // is named by a literal argument.
 //
 // mainPackagesOnly prints warnings for non-literal arguments that only match
 // non-main packages.
-func mainPackagesOnly(pkgs []*Package, patterns []string) []*Package {
-       matchers := make([]func(string) bool, len(patterns))
-       for i, p := range patterns {
-               if strings.Contains(p, "...") {
-                       matchers[i] = search.MatchPattern(p)
+func mainPackagesOnly(pkgs []*Package, matches []*search.Match) []*Package {
+       treatAsMain := map[string]bool{}
+       for _, m := range matches {
+               if m.IsLiteral() {
+                       for _, path := range m.Pkgs {
+                               treatAsMain[path] = true
+                       }
                }
        }
 
-       matchedPkgs := make([]*Package, 0, len(pkgs))
-       mainCount := make([]int, len(patterns))
-       nonMainCount := make([]int, len(patterns))
+       var mains []*Package
        for _, pkg := range pkgs {
-               if pkg.Name == "main" || (pkg.Incomplete && pkg.Name == "") {
-                       matchedPkgs = append(matchedPkgs, pkg)
-                       for i := range patterns {
-                               if matchers[i] != nil && matchers[i](pkg.ImportPath) {
-                                       mainCount[i]++
-                               }
-                       }
-               } else {
-                       for i := range patterns {
-                               if matchers[i] == nil && patterns[i] == pkg.ImportPath {
-                                       if pkg.Error == nil {
-                                               pkg.Error = &PackageError{Err: &mainPackageError{importPath: pkg.ImportPath}}
-                                       }
-                                       matchedPkgs = append(matchedPkgs, pkg)
-                               } else if matchers[i] != nil && matchers[i](pkg.ImportPath) {
-                                       nonMainCount[i]++
-                               }
+               if pkg.Name == "main" {
+                       treatAsMain[pkg.ImportPath] = true
+                       mains = append(mains, pkg)
+                       continue
+               }
+
+               if len(pkg.InvalidGoFiles) > 0 { // TODO(#45999): && pkg.Name == "", but currently go/build sets pkg.Name arbitrarily if it is ambiguous.
+                       // The package has (or may have) conflicting names, and we can't easily
+                       // tell whether one of them is "main". So assume that it could be, and
+                       // report an error for the package.
+                       treatAsMain[pkg.ImportPath] = true
+               }
+               if treatAsMain[pkg.ImportPath] {
+                       if pkg.Error == nil {
+                               pkg.Error = &PackageError{Err: &mainPackageError{importPath: pkg.ImportPath}}
                        }
+                       mains = append(mains, pkg)
                }
        }
-       for i, p := range patterns {
-               if matchers[i] != nil && mainCount[i] == 0 && nonMainCount[i] > 0 {
-                       fmt.Fprintf(os.Stderr, "go: warning: %q matched no main packages\n", p)
+
+       for _, m := range matches {
+               if m.IsLiteral() || len(m.Pkgs) == 0 {
+                       continue
+               }
+               foundMain := false
+               for _, path := range m.Pkgs {
+                       if treatAsMain[path] {
+                               foundMain = true
+                               break
+                       }
+               }
+               if !foundMain {
+                       fmt.Fprintf(os.Stderr, "go: warning: %q matched only non-main packages\n", m.Pattern())
                }
        }
 
-       return matchedPkgs
+       return mains
 }
 
 type mainPackageError struct {