internal/imports: save scanned module cache results
Save the packages found when scanning of the module cache.
The computed package may have a different import path due
to replace directives, so this needs to be updated
when the moduleResolver is initialized again.
Change-Id: Ib575fcc59b814ff263b431362df3698839a282f6
Reviewed-on: https://go-review.googlesource.com/c/tools/+/186301
Run-TryBot: Suzy Mueller <suzmue@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/internal/imports/mod.go b/internal/imports/mod.go
index 3d68533..7cc6c9d 100644
--- a/internal/imports/mod.go
+++ b/internal/imports/mod.go
@@ -27,6 +27,8 @@
Main *ModuleJSON
ModsByModPath []*ModuleJSON // All modules, ordered by # of path components in module Path...
ModsByDir []*ModuleJSON // ...or Dir.
+
+ ModCachePkgs map[string]*pkg // Packages in the mod cache, keyed by absolute directory.
}
type ModuleJSON struct {
@@ -87,6 +89,8 @@
return count(j) < count(i) // descending order
})
+ r.ModCachePkgs = make(map[string]*pkg)
+
r.Initialized = true
return nil
}
@@ -232,6 +236,15 @@
dupCheck[dir] = true
+ absDir := dir
+ // Packages in the module cache are immutable. If we have
+ // already seen this package on a previous scan of the module
+ // cache, return that result.
+ if p, ok := r.ModCachePkgs[absDir]; ok {
+ result = append(result, p)
+ return
+ }
+
subdir := ""
if dir != root.Path {
subdir = dir[len(root.Path)+len("/"):]
@@ -298,10 +311,18 @@
dir = canonicalDir
}
- result = append(result, &pkg{
+ res := &pkg{
importPathShort: VendorlessPath(importPath),
dir: dir,
- })
+ }
+
+ switch root.Type {
+ case gopathwalk.RootModuleCache:
+ // Save the results of processing this directory.
+ r.ModCachePkgs[absDir] = res
+ }
+
+ result = append(result, res)
}, gopathwalk.Options{Debug: r.env.Debug, ModulesEnabled: true})
return result, nil
}
diff --git a/internal/imports/mod_test.go b/internal/imports/mod_test.go
index e1d9c8c..a836307 100644
--- a/internal/imports/mod_test.go
+++ b/internal/imports/mod_test.go
@@ -118,6 +118,25 @@
mt.assertFound("example.com", "x")
}
+// Tests that scanning the module cache > 1 time is able to find the same module.
+func TestModMultipleScans(t *testing.T) {
+ mt := setup(t, `
+-- go.mod --
+module x
+
+require example.com v1.0.0
+
+-- x.go --
+package x
+import _ "example.com"
+`, "")
+ defer mt.cleanup()
+
+ mt.assertScanFinds("example.com", "x")
+ mt.assertScanFinds("example.com", "x")
+
+}
+
// Tests that -mod=vendor sort of works. Adapted from mod_getmode_vendor.txt.
func TestModeGetmodeVendor(t *testing.T) {
mt := setup(t, `
diff --git a/internal/lsp/source/format.go b/internal/lsp/source/format.go
index f7a5530..e9f12d2 100644
--- a/internal/lsp/source/format.go
+++ b/internal/lsp/source/format.go
@@ -75,6 +75,7 @@
resolver.Main = nil
resolver.ModsByModPath = nil
resolver.ModsByDir = nil
+ resolver.ModCachePkgs = nil
}
options := &imports.Options{
Env: view.ProcessEnv(ctx),