1
0
mirror of https://github.com/golang/go synced 2024-11-18 16:14:46 -07:00

internal/lsp: add ID to the package cache key

Our original caching plan was to use only the file ParseGoHandles as
cache keys to define a given package. However, because of package test
variants, we cannot rely on files alone. A package may have the exact
same set of files, but be a test variant. Add the ID to the key to avoid
clobbering entries in the cache.

Also, remove the unused metadata ID cache.

Change-Id: I4b33de1f83f6c769d23441e98a2a7324ff0fa1b0
Reviewed-on: https://go-review.googlesource.com/c/tools/+/194571
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
Rebecca Stambler 2019-09-10 17:33:35 -04:00
parent d0542c01b0
commit 3e6e7c4239
6 changed files with 24 additions and 5 deletions

View File

@ -43,6 +43,7 @@ type importer struct {
// checkPackageKey uniquely identifies a package and its config. // checkPackageKey uniquely identifies a package and its config.
type checkPackageKey struct { type checkPackageKey struct {
id string
files string files string
config string config string
@ -85,6 +86,7 @@ func (imp *importer) checkPackageHandle(ctx context.Context, m *metadata) (*chec
return nil, err return nil, err
} }
key := checkPackageKey{ key := checkPackageKey{
id: string(m.id),
files: hashParseKeys(phs), files: hashParseKeys(phs),
config: hashConfig(imp.config), config: hashConfig(imp.config),
} }
@ -144,6 +146,10 @@ func (cph *checkPackageHandle) Files() []source.ParseGoHandle {
return cph.files return cph.files
} }
func (cph *checkPackageHandle) ID() string {
return string(cph.m.id)
}
func (cph *checkPackageHandle) Cached(ctx context.Context) (source.Package, error) { func (cph *checkPackageHandle) Cached(ctx context.Context) (source.Package, error) {
v := cph.handle.Cached() v := cph.handle.Cached()
if v == nil { if v == nil {

View File

@ -278,7 +278,6 @@ func (v *view) link(ctx context.Context, g *importGraph) error {
// Add the metadata to the cache. // Add the metadata to the cache.
v.mcache.packages[m.id] = m v.mcache.packages[m.id] = m
v.mcache.ids[g.pkgPath] = m.id
// Connect the import graph. // Connect the import graph.
if g.parent != nil { if g.parent != nil {
@ -302,7 +301,7 @@ func (v *view) link(ctx context.Context, g *importGraph) error {
parent: m, parent: m,
missingImports: g.missingImports, missingImports: g.missingImports,
}); err != nil { }); err != nil {
log.Error(ctx, "error in dependecny", err) log.Error(ctx, "error in dependency", err)
} }
} }
} }

View File

@ -100,7 +100,6 @@ func (s *session) NewView(ctx context.Context, name string, folder span.URI, opt
filesByBase: make(map[string][]viewFile), filesByBase: make(map[string][]viewFile),
mcache: &metadataCache{ mcache: &metadataCache{
packages: make(map[packageID]*metadata), packages: make(map[packageID]*metadata),
ids: make(map[packagePath]packageID),
}, },
ignoredURIs: make(map[span.URI]struct{}), ignoredURIs: make(map[span.URI]struct{}),
} }

View File

@ -85,7 +85,6 @@ type view struct {
type metadataCache struct { type metadataCache struct {
mu sync.Mutex // guards both maps mu sync.Mutex // guards both maps
packages map[packageID]*metadata packages map[packageID]*metadata
ids map[packagePath]packageID
} }
type metadata struct { type metadata struct {
@ -423,6 +422,7 @@ func (v *view) remove(ctx context.Context, id packageID, seen map[packageID]stru
if cph, ok := gof.pkgs[id]; ok { if cph, ok := gof.pkgs[id]; ok {
// Delete the package handle from the store. // Delete the package handle from the store.
v.session.cache.store.Delete(checkPackageKey{ v.session.cache.store.Delete(checkPackageKey{
id: cph.ID(),
files: hashParseKeys(cph.Files()), files: hashParseKeys(cph.Files()),
config: hashConfig(cph.Config()), config: hashConfig(cph.Config()),
}) })

View File

@ -69,10 +69,22 @@ func Diagnostics(ctx context.Context, view View, f GoFile, disabledAnalyses map[
ctx, done := trace.StartSpan(ctx, "source.Diagnostics", telemetry.File.Of(f.URI())) ctx, done := trace.StartSpan(ctx, "source.Diagnostics", telemetry.File.Of(f.URI()))
defer done() defer done()
cph, err := f.GetCheckPackageHandle(ctx) cphs, err := f.GetCheckPackageHandles(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Use the "biggest" package we know about.
// If we know about a package and its in-package tests,
// we should send diagnostics for both.
var cph CheckPackageHandle
for _, h := range cphs {
if cph == nil || len(h.Files()) > len(cph.Files()) {
cph = h
}
}
if cph == nil {
return nil, errors.Errorf("no package for file %s", f.URI())
}
pkg, err := cph.Check(ctx) pkg, err := cph.Check(ctx)
if err != nil { if err != nil {
log.Error(ctx, "no package for file", err) log.Error(ctx, "no package for file", err)

View File

@ -109,6 +109,9 @@ const (
// CheckPackageHandle represents a handle to a specific version of a package. // CheckPackageHandle represents a handle to a specific version of a package.
// It is uniquely defined by the file handles that make up the package. // It is uniquely defined by the file handles that make up the package.
type CheckPackageHandle interface { type CheckPackageHandle interface {
// ID returns the ID of the package associated with the CheckPackageHandle.
ID() string
// ParseGoHandle returns a ParseGoHandle for which to get the package. // ParseGoHandle returns a ParseGoHandle for which to get the package.
Files() []ParseGoHandle Files() []ParseGoHandle