Skip to content

Commit

Permalink
deps: upgrade x/tools and gopls to 774c71fc
Browse files Browse the repository at this point in the history
* internal/lsp/cache: fix type error reporting in cgo 774c71fc
* internal/imports: actually skip things in scan 7bda3009
* internal/lsp: fix minor issues in diagnostic caching 6de373a2
* gopls/integration: save more precise parsing information 81ef4df1
* internal/lsp/cmd: fix documentation 27f5d1b1
* godoc/static: update copyright year to 2013 6ed6e603
* gopls/integration: cosmetic/ergonomic updates 9497f49d
* internal/lsp: miscellaneous cleanup 2aa90c60
* internal/imports: filter out self-import completions ba16e80a
* internal/imports: clean up dead code 1e586a53
* internal/lsp/source: scan loaded packages first for completions 9a28a1fa
* internal/imports: filter candidates on directory name 2f3125df
* internal/imports: filter roots with callback 872f4f41
* internal/imports: optimize scan implementations 7ec15289
* internal/imports,lsp: use callbacks for completion functions c2a8f45a
* internal/lsp: sort by label after score 3f7dfa39
* internal/lsp/source: always use default goimports options 0a57c092
* internal/imports: redesign scan API 50c778fb
* internal/imports: remove go/packages support ac3e9e73
* internal/lsp/source: don't get unnecessary unimported completions fd66c752
* internal/lsp: load metadata for a single package ID, when needed 234df48a
* all: remove many cases of space-space 6c68fec0
* go/analysis/analysistest: accept comments of /* */ form 2912ce79
* tools/internal/lsp/cmd: fix documentation 9fb4d214
* internal/lsp: create links for golang/go#1234-style strings 7b8e75db
* internal/lsp: refactor and document options 99d11d0e
* cmd/gopls: delete legacy gopls 8647d4c8
* internal/lsp/cmd: remove unnecessary message from help 819aba5d
* go/analysis: add package docs for findcall, printf, and shadow 065ed046
* gopls: use mvdan.cc/xurls for textDocument/documentLink 6b505deb
* internal/lsp: trim address operator from completion filterText dd894d0a
* internal/lsp: support taking address for completion candidates 3721262b
* internal/lsp: refactor find-implementation handling 918115ff
* internal/lsp/source: move some data onto "candidate" struct 4d2fe2ba
* internal/lsp/source: improve completion in value spec 7bd96bd5
* go/packages: fix TestCgoOption to work on Windows 142b776b
* internal/lsp: cleanup temporary go.mod file on shutdown c7341709
* gopls/doc: remove unnecessary settings from VSCode documentation a7b3459f
* gopls/integration: add a first cut of govim integration tests d7ab2451
* internal/lsp: make golint happy 8c5978f1
  • Loading branch information
myitcv committed Jan 5, 2020
1 parent 90dfc7d commit 80306a9
Show file tree
Hide file tree
Showing 48 changed files with 1,178 additions and 884 deletions.
429 changes: 182 additions & 247 deletions cmd/govim/internal/golang_org_x_tools/imports/fix.go

Large diffs are not rendered by default.

21 changes: 11 additions & 10 deletions cmd/govim/internal/golang_org_x_tools/imports/imports.go
Expand Up @@ -11,6 +11,7 @@ package imports
import (
"bufio"
"bytes"
"context"
"fmt"
"go/ast"
"go/build"
Expand Down Expand Up @@ -115,23 +116,23 @@ func ApplyFixes(fixes []*ImportFix, filename string, src []byte, opt *Options, e
return formatFile(fileSet, file, src, nil, opt)
}

// GetAllCandidates gets all of the standard library candidate packages to import in
// sorted order on import path.
func GetAllCandidates(filename string, opt *Options) (pkgs []ImportFix, err error) {
_, opt, err = initialize(filename, nil, opt)
// GetAllCandidates gets all of the packages starting with prefix that can be
// imported by filename, sorted by import path.
func GetAllCandidates(ctx context.Context, callback func(ImportFix), searchPrefix, filename, filePkg string, opt *Options) error {
_, opt, err := initialize(filename, nil, opt)
if err != nil {
return nil, err
return err
}
return getAllCandidates(filename, opt.Env)
return getAllCandidates(ctx, callback, searchPrefix, filename, filePkg, opt.Env)
}

// GetPackageExports returns all known packages with name pkg and their exports.
func GetPackageExports(pkg, filename string, opt *Options) (exports []PackageExport, err error) {
_, opt, err = initialize(filename, nil, opt)
func GetPackageExports(ctx context.Context, callback func(PackageExport), searchPkg, filename, filePkg string, opt *Options) error {
_, opt, err := initialize(filename, nil, opt)
if err != nil {
return nil, err
return err
}
return getPackageExports(pkg, filename, opt.Env)
return getPackageExports(ctx, callback, searchPkg, filename, filePkg, opt.Env)
}

// initialize sets the values for opt and src.
Expand Down
174 changes: 102 additions & 72 deletions cmd/govim/internal/golang_org_x_tools/imports/mod.go
Expand Up @@ -13,7 +13,6 @@ import (
"sort"
"strconv"
"strings"
"sync"

"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/gopathwalk"
"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/module"
Expand All @@ -26,6 +25,8 @@ type ModuleResolver struct {
env *ProcessEnv
moduleCacheDir string
dummyVendorMod *ModuleJSON // If vendoring is enabled, the pseudo-module that represents the /vendor directory.
roots []gopathwalk.Root
scannedRoots map[gopathwalk.Root]bool

Initialized bool
Main *ModuleJSON
Expand Down Expand Up @@ -86,6 +87,38 @@ func (r *ModuleResolver) init() error {
return count(j) < count(i) // descending order
})

r.roots = []gopathwalk.Root{
{filepath.Join(r.env.GOROOT, "/src"), gopathwalk.RootGOROOT},
}
if r.Main != nil {
r.roots = append(r.roots, gopathwalk.Root{r.Main.Dir, gopathwalk.RootCurrentModule})
}
if vendorEnabled {
r.roots = append(r.roots, gopathwalk.Root{r.dummyVendorMod.Dir, gopathwalk.RootOther})
} else {
addDep := func(mod *ModuleJSON) {
if mod.Replace == nil {
// This is redundant with the cache, but we'll skip it cheaply enough.
r.roots = append(r.roots, gopathwalk.Root{mod.Dir, gopathwalk.RootModuleCache})
} else {
r.roots = append(r.roots, gopathwalk.Root{mod.Dir, gopathwalk.RootOther})
}
}
// Walk dependent modules before scanning the full mod cache, direct deps first.
for _, mod := range r.ModsByModPath {
if !mod.Indirect {
addDep(mod)
}
}
for _, mod := range r.ModsByModPath {
if mod.Indirect {
addDep(mod)
}
}
r.roots = append(r.roots, gopathwalk.Root{r.moduleCacheDir, gopathwalk.RootModuleCache})
}

r.scannedRoots = map[gopathwalk.Root]bool{}
if r.moduleCacheCache == nil {
r.moduleCacheCache = &dirInfoCache{
dirs: map[string]*directoryPackageInfo{},
Expand Down Expand Up @@ -127,6 +160,7 @@ func (r *ModuleResolver) initAllMods() error {
}

func (r *ModuleResolver) ClearForNewScan() {
r.scannedRoots = map[gopathwalk.Root]bool{}
r.otherCache = &dirInfoCache{
dirs: map[string]*directoryPackageInfo{},
}
Expand Down Expand Up @@ -212,7 +246,7 @@ func (r *ModuleResolver) cacheKeys() []string {
}

// cachePackageName caches the package name for a dir already in the cache.
func (r *ModuleResolver) cachePackageName(info directoryPackageInfo) (directoryPackageInfo, error) {
func (r *ModuleResolver) cachePackageName(info directoryPackageInfo) (string, error) {
if info.rootType == gopathwalk.RootModuleCache {
return r.moduleCacheCache.CachePackageName(info)
}
Expand Down Expand Up @@ -334,41 +368,55 @@ func (r *ModuleResolver) loadPackageNames(importPaths []string, srcDir string) (
return names, nil
}

func (r *ModuleResolver) scan(_ references, loadNames bool, exclude []gopathwalk.RootType) ([]*pkg, error) {
func (r *ModuleResolver) scan(ctx context.Context, callback *scanCallback) error {
if err := r.init(); err != nil {
return nil, err
return err
}

// Walk GOROOT, GOPATH/pkg/mod, and the main module.
roots := []gopathwalk.Root{
{filepath.Join(r.env.GOROOT, "/src"), gopathwalk.RootGOROOT},
}
if r.Main != nil {
roots = append(roots, gopathwalk.Root{r.Main.Dir, gopathwalk.RootCurrentModule})
}
if r.dummyVendorMod != nil {
roots = append(roots, gopathwalk.Root{r.dummyVendorMod.Dir, gopathwalk.RootOther})
} else {
roots = append(roots, gopathwalk.Root{r.moduleCacheDir, gopathwalk.RootModuleCache})
// Walk replace targets, just in case they're not in any of the above.
for _, mod := range r.ModsByModPath {
if mod.Replace != nil {
roots = append(roots, gopathwalk.Root{mod.Dir, gopathwalk.RootOther})
}
processDir := func(info directoryPackageInfo) {
// Skip this directory if we were not able to get the package information successfully.
if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil {
return
}
pkg, err := r.canonicalize(info)
if err != nil {
return
}
}

roots = filterRoots(roots, exclude)
if !callback.dirFound(pkg) {
return
}
pkg.packageName, err = r.cachePackageName(info)
if err != nil {
return
}

var result []*pkg
var mu sync.Mutex
if !callback.packageNameLoaded(pkg) {
return
}
_, exports, err := r.loadExports(ctx, pkg)
if err != nil {
return
}
callback.exportsLoaded(pkg, exports)
}

// We assume cached directories have not changed. We can skip them and their
// children.
skip := func(root gopathwalk.Root, dir string) bool {
mu.Lock()
defer mu.Unlock()
// Everything we already had is in the cache. Process it now, in hopes we
// we don't need anything new.
for _, dir := range r.cacheKeys() {
if ctx.Err() != nil {
return nil
}
info, ok := r.cacheLoad(dir)
if !ok {
continue
}
processDir(info)
}

// We assume cached directories are fully cached, including all their
// children, and have not changed. We can skip them.
skip := func(root gopathwalk.Root, dir string) bool {
info, ok := r.cacheLoad(dir)
if !ok {
return false
Expand All @@ -380,44 +428,34 @@ func (r *ModuleResolver) scan(_ references, loadNames bool, exclude []gopathwalk
return packageScanned
}

// Add anything new to the cache. We'll process everything in it below.
// Add anything new to the cache, and process it if we're still looking.
add := func(root gopathwalk.Root, dir string) {
mu.Lock()
defer mu.Unlock()

r.cacheStore(r.scanDirForPackage(root, dir))
info := r.scanDirForPackage(root, dir)
r.cacheStore(info)
if ctx.Err() == nil {
processDir(info)
}
}

gopathwalk.WalkSkip(roots, add, skip, gopathwalk.Options{Debug: r.env.Debug, ModulesEnabled: true})

// Everything we already had, and everything new, is now in the cache.
for _, dir := range r.cacheKeys() {
info, ok := r.cacheLoad(dir)
if !ok {
continue
// We can't cancel walks, because we need them to finish to have a usable
// cache. We can do them one by one and stop in between.
// TODO(heschi): Run asynchronously and detach on cancellation? Would risk
// racy callbacks.
for _, root := range r.roots {
if ctx.Err() != nil {
return nil
}

// Skip this directory if we were not able to get the package information successfully.
if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil {
if r.scannedRoots[root] {
continue
}

// If we want package names, make sure the cache has them.
if loadNames {
var err error
if info, err = r.cachePackageName(info); err != nil {
continue
}
}

res, err := r.canonicalize(info)
if err != nil {
if !callback.rootFound(root) {
continue
}
result = append(result, res)
gopathwalk.WalkSkip([]gopathwalk.Root{root}, add, skip, gopathwalk.Options{Debug: r.env.Debug, ModulesEnabled: true})
r.scannedRoots[root] = true
}

return result, nil
return nil
}

// canonicalize gets the result of canonicalizing the packages using the results
Expand All @@ -429,18 +467,18 @@ func (r *ModuleResolver) canonicalize(info directoryPackageInfo) (*pkg, error) {
importPathShort: info.nonCanonicalImportPath,
dir: info.dir,
packageName: path.Base(info.nonCanonicalImportPath),
relevance: 0,
relevance: MaxRelevance,
}, nil
}

importPath := info.nonCanonicalImportPath
relevance := 3
relevance := MaxRelevance - 3
// Check if the directory is underneath a module that's in scope.
if mod := r.findModuleByDir(info.dir); mod != nil {
if mod.Indirect {
relevance = 2
relevance = MaxRelevance - 2
} else {
relevance = 1
relevance = MaxRelevance - 1
}
// It is. If dir is the target of a replace directive,
// our guessed import path is wrong. Use the real one.
Expand All @@ -450,14 +488,15 @@ func (r *ModuleResolver) canonicalize(info directoryPackageInfo) (*pkg, error) {
dirInMod := info.dir[len(mod.Dir)+len("/"):]
importPath = path.Join(mod.Path, filepath.ToSlash(dirInMod))
}
} else if info.needsReplace {
} else if !strings.HasPrefix(importPath, info.moduleName) {
// The module's name doesn't match the package's import path. It
// probably needs a replace directive we don't have.
return nil, fmt.Errorf("package in %q is not valid without a replace statement", info.dir)
}

res := &pkg{
importPathShort: importPath,
dir: info.dir,
packageName: info.packageName, // may not be populated if the caller didn't ask for it
relevance: relevance,
}
// We may have discovered a package that has a different version
Expand Down Expand Up @@ -521,22 +560,13 @@ func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) dir
dir: dir,
rootType: root.Type,
nonCanonicalImportPath: importPath,
needsReplace: false,
moduleDir: modDir,
moduleName: modName,
}
if root.Type == gopathwalk.RootGOROOT {
// stdlib packages are always in scope, despite the confusing go.mod
return result
}
// Check that this package is not obviously impossible to import.
if !strings.HasPrefix(importPath, modName) {
// The module's declared path does not match
// its expected path. It probably needs a
// replace directive we don't have.
result.needsReplace = true
}

return result
}

Expand Down
14 changes: 5 additions & 9 deletions cmd/govim/internal/golang_org_x_tools/imports/mod_cache.go
Expand Up @@ -49,10 +49,6 @@ type directoryPackageInfo struct {
// nonCanonicalImportPath is the package's expected import path. It may
// not actually be importable at that path.
nonCanonicalImportPath string
// needsReplace is true if the nonCanonicalImportPath does not match the
// module's declared path, making it impossible to import without a
// replace directive.
needsReplace bool

// Module-related information.
moduleDir string // The directory that is the module root of this dir.
Expand Down Expand Up @@ -129,17 +125,17 @@ func (d *dirInfoCache) Keys() (keys []string) {
return keys
}

func (d *dirInfoCache) CachePackageName(info directoryPackageInfo) (directoryPackageInfo, error) {
func (d *dirInfoCache) CachePackageName(info directoryPackageInfo) (string, error) {
if loaded, err := info.reachedStatus(nameLoaded); loaded {
return info, err
return info.packageName, err
}
if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil {
return info, fmt.Errorf("cannot read package name, scan error: %v", err)
return "", fmt.Errorf("cannot read package name, scan error: %v", err)
}
info.packageName, info.err = packageDirToName(info.dir)
info.status = nameLoaded
d.Store(info.dir, info)
return info, info.err
return info.packageName, info.err
}

func (d *dirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []string, error) {
Expand All @@ -150,7 +146,7 @@ func (d *dirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info d
return "", nil, err
}
info.packageName, info.exports, info.err = loadExportsFromFiles(ctx, env, info.dir)
if info.err == context.Canceled {
if info.err == context.Canceled || info.err == context.DeadlineExceeded {
return info.packageName, info.exports, info.err
}
// The cache structure wants things to proceed linearly. We can skip a
Expand Down
6 changes: 3 additions & 3 deletions cmd/govim/internal/golang_org_x_tools/lsp/cache/check.go
Expand Up @@ -58,8 +58,8 @@ type packageData struct {
err error
}

// packageHandle returns a source.CheckPackageHandle for a given package and config.
func (s *snapshot) packageHandle(ctx context.Context, id packageID, mode source.ParseMode) (*packageHandle, error) {
// buildPackageHandle returns a source.CheckPackageHandle for a given package and config.
func (s *snapshot) buildPackageHandle(ctx context.Context, id packageID, mode source.ParseMode) (*packageHandle, error) {
// Check if we already have this CheckPackageHandle cached.
if ph := s.getPackage(id, mode); ph != nil {
return ph, nil
Expand Down Expand Up @@ -140,7 +140,7 @@ func (s *snapshot) buildKey(ctx context.Context, id packageID, mode source.Parse
if s.workspacePackages[depID] {
mode = source.ParseFull
}
depHandle, err := s.packageHandle(ctx, depID, mode)
depHandle, err := s.buildPackageHandle(ctx, depID, mode)
if err != nil {
log.Error(ctx, "no dep handle", err, telemetry.Package.Of(depID))

Expand Down

0 comments on commit 80306a9

Please sign in to comment.