29
vendor/golang.org/x/tools/go/packages/external.go
generated
vendored
29
vendor/golang.org/x/tools/go/packages/external.go
generated
vendored
@@ -16,14 +16,29 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Driver
|
||||
// The Driver Protocol
|
||||
//
|
||||
// The driver, given the inputs to a call to Load, returns metadata about the packages specified.
|
||||
// This allows for different build systems to support go/packages by telling go/packages how the
|
||||
// packages' source is organized.
|
||||
// The driver is a binary, either specified by the GOPACKAGESDRIVER environment variable or in
|
||||
// the path as gopackagesdriver. It's given the inputs to load in its argv. See the package
|
||||
// documentation in doc.go for the full description of the patterns that need to be supported.
|
||||
// A driver receives as a JSON-serialized driverRequest struct in standard input and will
|
||||
// produce a JSON-serialized driverResponse (see definition in packages.go) in its standard output.
|
||||
|
||||
// driverRequest is used to provide the portion of Load's Config that is needed by a driver.
|
||||
type driverRequest struct {
|
||||
Command string `json:"command"`
|
||||
Mode LoadMode `json:"mode"`
|
||||
Env []string `json:"env"`
|
||||
BuildFlags []string `json:"build_flags"`
|
||||
Tests bool `json:"tests"`
|
||||
Overlay map[string][]byte `json:"overlay"`
|
||||
Mode LoadMode `json:"mode"`
|
||||
// Env specifies the environment the underlying build system should be run in.
|
||||
Env []string `json:"env"`
|
||||
// BuildFlags are flags that should be passed to the underlying build system.
|
||||
BuildFlags []string `json:"build_flags"`
|
||||
// Tests specifies whether the patterns should also return test packages.
|
||||
Tests bool `json:"tests"`
|
||||
// Overlay maps file paths (relative to the driver's working directory) to the byte contents
|
||||
// of overlay files.
|
||||
Overlay map[string][]byte `json:"overlay"`
|
||||
}
|
||||
|
||||
// findExternalDriver returns the file path of a tool that supplies
|
||||
|
||||
22
vendor/golang.org/x/tools/go/packages/golist.go
generated
vendored
22
vendor/golang.org/x/tools/go/packages/golist.go
generated
vendored
@@ -158,7 +158,7 @@ extractQueries:
|
||||
}
|
||||
}
|
||||
|
||||
modifiedPkgs, needPkgs, err := processGolistOverlay(cfg, response.dr)
|
||||
modifiedPkgs, needPkgs, err := processGolistOverlay(cfg, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -209,11 +209,13 @@ func addNeededOverlayPackages(cfg *Config, driver driver, response *responseDedu
|
||||
for _, pkg := range dr.Packages {
|
||||
response.addPackage(pkg)
|
||||
}
|
||||
_, needPkgs, err := processGolistOverlay(cfg, response.dr)
|
||||
_, needPkgs, err := processGolistOverlay(cfg, response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addNeededOverlayPackages(cfg, driver, response, needPkgs)
|
||||
if err := addNeededOverlayPackages(cfg, driver, response, needPkgs); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -228,8 +230,16 @@ func runContainsQueries(cfg *Config, driver driver, response *responseDeduper, q
|
||||
return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err)
|
||||
}
|
||||
dirResponse, err := driver(cfg, pattern)
|
||||
if err != nil {
|
||||
return err
|
||||
if err != nil || (len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].Errors) == 1) {
|
||||
// There was an error loading the package. Try to load the file as an ad-hoc package.
|
||||
// Usually the error will appear in a returned package, but may not if we're in modules mode
|
||||
// and the ad-hoc is located outside a module.
|
||||
var queryErr error
|
||||
dirResponse, queryErr = driver(cfg, query)
|
||||
if queryErr != nil {
|
||||
// Return the original error if the attempt to fall back failed.
|
||||
return err
|
||||
}
|
||||
}
|
||||
isRoot := make(map[string]bool, len(dirResponse.Roots))
|
||||
for _, root := range dirResponse.Roots {
|
||||
@@ -693,7 +703,7 @@ func golistDriver(cfg *Config, words ...string) (*driverResponse, error) {
|
||||
if p.Error != nil {
|
||||
pkg.Errors = append(pkg.Errors, Error{
|
||||
Pos: p.Error.Pos,
|
||||
Msg: p.Error.Err,
|
||||
Msg: strings.TrimSpace(p.Error.Err), // Trim to work around golang.org/issue/32363.
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
80
vendor/golang.org/x/tools/go/packages/golist_overlay.go
generated
vendored
80
vendor/golang.org/x/tools/go/packages/golist_overlay.go
generated
vendored
@@ -3,6 +3,7 @@ package packages
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"path"
|
||||
@@ -16,16 +17,13 @@ import (
|
||||
// files that don't exist on disk to an overlay. The results can be
|
||||
// sometimes incorrect.
|
||||
// TODO(matloob): Handle unsupported cases, including the following:
|
||||
// - test files
|
||||
// - adding test and non-test files to test variants of packages
|
||||
// - determining the correct package to add given a new import path
|
||||
// - creating packages that don't exist
|
||||
func processGolistOverlay(cfg *Config, response *driverResponse) (modifiedPkgs, needPkgs []string, err error) {
|
||||
func processGolistOverlay(cfg *Config, response *responseDeduper) (modifiedPkgs, needPkgs []string, err error) {
|
||||
havePkgs := make(map[string]string) // importPath -> non-test package ID
|
||||
needPkgsSet := make(map[string]bool)
|
||||
modifiedPkgsSet := make(map[string]bool)
|
||||
|
||||
for _, pkg := range response.Packages {
|
||||
for _, pkg := range response.dr.Packages {
|
||||
// This is an approximation of import path to id. This can be
|
||||
// wrong for tests, vendored packages, and a number of other cases.
|
||||
havePkgs[pkg.PkgPath] = pkg.ID
|
||||
@@ -34,21 +32,42 @@ func processGolistOverlay(cfg *Config, response *driverResponse) (modifiedPkgs,
|
||||
var rootDirs map[string]string
|
||||
var onceGetRootDirs sync.Once
|
||||
|
||||
// If no new imports are added, it is safe to avoid loading any needPkgs.
|
||||
// Otherwise, it's hard to tell which package is actually being loaded
|
||||
// (due to vendoring) and whether any modified package will show up
|
||||
// in the transitive set of dependencies (because new imports are added,
|
||||
// potentially modifying the transitive set of dependencies).
|
||||
var overlayAddsImports bool
|
||||
|
||||
for opath, contents := range cfg.Overlay {
|
||||
base := filepath.Base(opath)
|
||||
if strings.HasSuffix(opath, "_test.go") {
|
||||
// Overlays don't support adding new test files yet.
|
||||
// TODO(matloob): support adding new test files.
|
||||
continue
|
||||
}
|
||||
dir := filepath.Dir(opath)
|
||||
var pkg *Package
|
||||
var testVariantOf *Package // if opath is a test file, this is the package it is testing
|
||||
var fileExists bool
|
||||
for _, p := range response.Packages {
|
||||
isTest := strings.HasSuffix(opath, "_test.go")
|
||||
pkgName, ok := extractPackageName(opath, contents)
|
||||
if !ok {
|
||||
// Don't bother adding a file that doesn't even have a parsable package statement
|
||||
// to the overlay.
|
||||
continue
|
||||
}
|
||||
nextPackage:
|
||||
for _, p := range response.dr.Packages {
|
||||
if pkgName != p.Name {
|
||||
continue
|
||||
}
|
||||
for _, f := range p.GoFiles {
|
||||
if !sameFile(filepath.Dir(f), dir) {
|
||||
continue
|
||||
}
|
||||
if isTest && !hasTestFiles(p) {
|
||||
// TODO(matloob): Are there packages other than the 'production' variant
|
||||
// of a package that this can match? This shouldn't match the test main package
|
||||
// because the file is generated in another directory.
|
||||
testVariantOf = p
|
||||
continue nextPackage
|
||||
}
|
||||
pkg = p
|
||||
if filepath.Base(f) == base {
|
||||
fileExists = true
|
||||
@@ -82,13 +101,16 @@ func processGolistOverlay(cfg *Config, response *driverResponse) (modifiedPkgs,
|
||||
if pkgPath == "" {
|
||||
continue
|
||||
}
|
||||
pkgName, ok := extractPackageName(opath, contents)
|
||||
if !ok {
|
||||
continue
|
||||
isXTest := strings.HasSuffix(pkgName, "_test")
|
||||
if isXTest {
|
||||
pkgPath += "_test"
|
||||
}
|
||||
id := pkgPath
|
||||
if isTest && !isXTest {
|
||||
id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath)
|
||||
}
|
||||
// Try to reclaim a package with the same id if it exists in the response.
|
||||
for _, p := range response.Packages {
|
||||
for _, p := range response.dr.Packages {
|
||||
if reclaimPackage(p, id, opath, contents) {
|
||||
pkg = p
|
||||
break
|
||||
@@ -97,9 +119,13 @@ func processGolistOverlay(cfg *Config, response *driverResponse) (modifiedPkgs,
|
||||
// Otherwise, create a new package
|
||||
if pkg == nil {
|
||||
pkg = &Package{PkgPath: pkgPath, ID: id, Name: pkgName, Imports: make(map[string]*Package)}
|
||||
// TODO(matloob): Is it okay to amend response.Packages this way?
|
||||
response.Packages = append(response.Packages, pkg)
|
||||
response.addPackage(pkg)
|
||||
havePkgs[pkg.PkgPath] = id
|
||||
// Add the production package's sources for a test variant.
|
||||
if isTest && !isXTest && testVariantOf != nil {
|
||||
pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...)
|
||||
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...)
|
||||
}
|
||||
}
|
||||
}
|
||||
if !fileExists {
|
||||
@@ -117,6 +143,7 @@ func processGolistOverlay(cfg *Config, response *driverResponse) (modifiedPkgs,
|
||||
for _, imp := range imports {
|
||||
_, found := pkg.Imports[imp]
|
||||
if !found {
|
||||
overlayAddsImports = true
|
||||
// TODO(matloob): Handle cases when the following block isn't correct.
|
||||
// These include imports of test variants, imports of vendored packages, etc.
|
||||
id, ok := havePkgs[imp]
|
||||
@@ -143,7 +170,7 @@ func processGolistOverlay(cfg *Config, response *driverResponse) (modifiedPkgs,
|
||||
|
||||
// Do another pass now that new packages have been created to determine the
|
||||
// set of missing packages.
|
||||
for _, pkg := range response.Packages {
|
||||
for _, pkg := range response.dr.Packages {
|
||||
for _, imp := range pkg.Imports {
|
||||
pkgPath := toPkgPath(imp.ID)
|
||||
if _, ok := havePkgs[pkgPath]; !ok {
|
||||
@@ -152,9 +179,11 @@ func processGolistOverlay(cfg *Config, response *driverResponse) (modifiedPkgs,
|
||||
}
|
||||
}
|
||||
|
||||
needPkgs = make([]string, 0, len(needPkgsSet))
|
||||
for pkg := range needPkgsSet {
|
||||
needPkgs = append(needPkgs, pkg)
|
||||
if overlayAddsImports {
|
||||
needPkgs = make([]string, 0, len(needPkgsSet))
|
||||
for pkg := range needPkgsSet {
|
||||
needPkgs = append(needPkgs, pkg)
|
||||
}
|
||||
}
|
||||
modifiedPkgs = make([]string, 0, len(modifiedPkgsSet))
|
||||
for pkg := range modifiedPkgsSet {
|
||||
@@ -163,6 +192,15 @@ func processGolistOverlay(cfg *Config, response *driverResponse) (modifiedPkgs,
|
||||
return modifiedPkgs, needPkgs, err
|
||||
}
|
||||
|
||||
func hasTestFiles(p *Package) bool {
|
||||
for _, f := range p.GoFiles {
|
||||
if strings.HasSuffix(f, "_test.go") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// determineRootDirs returns a mapping from directories code can be contained in to the
|
||||
// corresponding import path prefixes of those directories.
|
||||
// Its result is used to try to determine the import path for a package containing
|
||||
|
||||
42
vendor/golang.org/x/tools/go/packages/packages.go
generated
vendored
42
vendor/golang.org/x/tools/go/packages/packages.go
generated
vendored
@@ -527,28 +527,32 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
||||
lpkg.color = grey
|
||||
stack = append(stack, lpkg) // push
|
||||
stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
|
||||
lpkg.Imports = make(map[string]*Package, len(stubs))
|
||||
for importPath, ipkg := range stubs {
|
||||
var importErr error
|
||||
imp := ld.pkgs[ipkg.ID]
|
||||
if imp == nil {
|
||||
// (includes package "C" when DisableCgo)
|
||||
importErr = fmt.Errorf("missing package: %q", ipkg.ID)
|
||||
} else if imp.color == grey {
|
||||
importErr = fmt.Errorf("import cycle: %s", stack)
|
||||
}
|
||||
if importErr != nil {
|
||||
if lpkg.importErrors == nil {
|
||||
lpkg.importErrors = make(map[string]error)
|
||||
// If NeedImports isn't set, the imports fields will all be zeroed out.
|
||||
// If NeedDeps isn't also set we want to keep the stubs.
|
||||
if ld.Mode&NeedImports != 0 && ld.Mode&NeedDeps != 0 {
|
||||
lpkg.Imports = make(map[string]*Package, len(stubs))
|
||||
for importPath, ipkg := range stubs {
|
||||
var importErr error
|
||||
imp := ld.pkgs[ipkg.ID]
|
||||
if imp == nil {
|
||||
// (includes package "C" when DisableCgo)
|
||||
importErr = fmt.Errorf("missing package: %q", ipkg.ID)
|
||||
} else if imp.color == grey {
|
||||
importErr = fmt.Errorf("import cycle: %s", stack)
|
||||
}
|
||||
if importErr != nil {
|
||||
if lpkg.importErrors == nil {
|
||||
lpkg.importErrors = make(map[string]error)
|
||||
}
|
||||
lpkg.importErrors[importPath] = importErr
|
||||
continue
|
||||
}
|
||||
lpkg.importErrors[importPath] = importErr
|
||||
continue
|
||||
}
|
||||
|
||||
if visit(imp) {
|
||||
lpkg.needsrc = true
|
||||
if visit(imp) {
|
||||
lpkg.needsrc = true
|
||||
}
|
||||
lpkg.Imports[importPath] = imp.Package
|
||||
}
|
||||
lpkg.Imports[importPath] = imp.Package
|
||||
}
|
||||
if lpkg.needsrc {
|
||||
srcPkgs = append(srcPkgs, lpkg)
|
||||
|
||||
Reference in New Issue
Block a user