mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
internal/lsp: add analyses to the snapshot
This change makes sure that actionHandles are cached within the snapshot, to minimize the cost of re-computing action handles on each run of go/analysis. Change-Id: If6191c5224285eb207aebb997787ea551a47fbaa Reviewed-on: https://go-review.googlesource.com/c/tools/+/201098 Run-TryBot: Rebecca Stambler <rstambler@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
parent
18e3458ac9
commit
f936694f27
16
internal/lsp/cache/analysis.go
vendored
16
internal/lsp/cache/analysis.go
vendored
@ -17,6 +17,11 @@ import (
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type actionKey struct {
|
||||
pkg packageKey
|
||||
analyzer string // analyzer name
|
||||
}
|
||||
|
||||
func (s *snapshot) Analyze(ctx context.Context, id string, analyzers []*analysis.Analyzer) (map[*analysis.Analyzer][]*analysis.Diagnostic, error) {
|
||||
var roots []*actionHandle
|
||||
|
||||
@ -79,6 +84,10 @@ type packageFactKey struct {
|
||||
}
|
||||
|
||||
func (s *snapshot) actionHandle(ctx context.Context, id packageID, mode source.ParseMode, a *analysis.Analyzer) (*actionHandle, error) {
|
||||
ah := s.getAction(id, mode, a.Name)
|
||||
if ah != nil {
|
||||
return ah, nil
|
||||
}
|
||||
cph := s.getPackage(id, mode)
|
||||
if cph == nil {
|
||||
return nil, errors.Errorf("no CheckPackageHandle for %s:%v", id, mode == source.ParseExported)
|
||||
@ -90,7 +99,7 @@ func (s *snapshot) actionHandle(ctx context.Context, id packageID, mode source.P
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ah := &actionHandle{
|
||||
ah = &actionHandle{
|
||||
analyzer: a,
|
||||
pkg: pkg,
|
||||
}
|
||||
@ -118,12 +127,13 @@ func (s *snapshot) actionHandle(ctx context.Context, id packageID, mode source.P
|
||||
ah.deps = append(ah.deps, depActionHandle)
|
||||
}
|
||||
}
|
||||
h := s.view.session.cache.store.Bind(actionKey(a, cph), func(ctx context.Context) interface{} {
|
||||
h := s.view.session.cache.store.Bind(buildActionKey(a, cph), func(ctx context.Context) interface{} {
|
||||
data := &actionData{}
|
||||
data.diagnostics, data.result, data.err = ah.exec(ctx, s.view.session.cache.fset)
|
||||
return data
|
||||
})
|
||||
ah.handle = h
|
||||
s.addAction(ah)
|
||||
return ah, nil
|
||||
}
|
||||
|
||||
@ -136,7 +146,7 @@ func (ah *actionHandle) analyze(ctx context.Context) ([]*analysis.Diagnostic, in
|
||||
return data.diagnostics, data.result, data.err
|
||||
}
|
||||
|
||||
func actionKey(a *analysis.Analyzer, cph *checkPackageHandle) string {
|
||||
func buildActionKey(a *analysis.Analyzer, cph *checkPackageHandle) string {
|
||||
return hashContents([]byte(fmt.Sprintf("%s %s", a, string(cph.key))))
|
||||
}
|
||||
|
||||
|
1
internal/lsp/cache/check.go
vendored
1
internal/lsp/cache/check.go
vendored
@ -266,6 +266,7 @@ func (imp *importer) typeCheck(ctx context.Context, cph *checkPackageHandle) (*p
|
||||
pkg := &pkg{
|
||||
view: imp.snapshot.view,
|
||||
id: cph.m.id,
|
||||
mode: cph.mode,
|
||||
pkgPath: cph.m.pkgPath,
|
||||
files: cph.Files(),
|
||||
imports: make(map[packagePath]*pkg),
|
||||
|
1
internal/lsp/cache/pkg.go
vendored
1
internal/lsp/cache/pkg.go
vendored
@ -24,6 +24,7 @@ type pkg struct {
|
||||
|
||||
// ID and package path have their own types to avoid being used interchangeably.
|
||||
id packageID
|
||||
mode source.ParseMode
|
||||
pkgPath packagePath
|
||||
files []source.ParseGoHandle
|
||||
errors []packages.Error
|
||||
|
1
internal/lsp/cache/session.go
vendored
1
internal/lsp/cache/session.go
vendored
@ -104,6 +104,7 @@ func (s *session) NewView(ctx context.Context, name string, folder span.URI, opt
|
||||
metadata: make(map[packageID]*metadata),
|
||||
files: make(map[span.URI]source.FileHandle),
|
||||
importedBy: make(map[packageID][]packageID),
|
||||
actions: make(map[actionKey]*actionHandle),
|
||||
},
|
||||
ignoredURIs: make(map[span.URI]struct{}),
|
||||
builtin: &builtinPkg{},
|
||||
|
47
internal/lsp/cache/snapshot.go
vendored
47
internal/lsp/cache/snapshot.go
vendored
@ -29,9 +29,12 @@ type snapshot struct {
|
||||
// It may invalidated when a file's content changes.
|
||||
files map[span.URI]source.FileHandle
|
||||
|
||||
// packages maps a file URI to a set of CheckPackageHandles to which that file belongs.
|
||||
// packages maps a packageKey to a set of CheckPackageHandles to which that file belongs.
|
||||
// It may be invalidated when a file's content changes.
|
||||
packages map[packageKey]*checkPackageHandle
|
||||
|
||||
// actions maps an actionkey to its actionHandle.
|
||||
actions map[actionKey]*actionHandle
|
||||
}
|
||||
|
||||
func (s *snapshot) View() source.View {
|
||||
@ -93,6 +96,37 @@ func (s *snapshot) getPackage(id packageID, m source.ParseMode) *checkPackageHan
|
||||
return s.packages[key]
|
||||
}
|
||||
|
||||
func (s *snapshot) getAction(id packageID, m source.ParseMode, analyzer string) *actionHandle {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
key := actionKey{
|
||||
pkg: packageKey{
|
||||
id: id,
|
||||
mode: m,
|
||||
},
|
||||
analyzer: analyzer,
|
||||
}
|
||||
return s.actions[key]
|
||||
}
|
||||
|
||||
func (s *snapshot) addAction(ah *actionHandle) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
key := actionKey{
|
||||
analyzer: ah.analyzer.Name,
|
||||
pkg: packageKey{
|
||||
id: ah.pkg.id,
|
||||
mode: ah.pkg.mode,
|
||||
},
|
||||
}
|
||||
if _, ok := s.actions[key]; ok {
|
||||
return
|
||||
}
|
||||
s.actions[key] = ah
|
||||
}
|
||||
|
||||
func (s *snapshot) getMetadataForURI(uri span.URI) (metadata []*metadata) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
@ -175,6 +209,7 @@ func (s *snapshot) clone(ctx context.Context, withoutURI *span.URI, withoutTypes
|
||||
importedBy: make(map[packageID][]packageID),
|
||||
metadata: make(map[packageID]*metadata),
|
||||
packages: make(map[packageKey]*checkPackageHandle),
|
||||
actions: make(map[actionKey]*actionHandle),
|
||||
files: make(map[span.URI]source.FileHandle),
|
||||
}
|
||||
// Copy all of the FileHandles except for the one that was invalidated.
|
||||
@ -216,6 +251,16 @@ func (s *snapshot) clone(ctx context.Context, withoutURI *span.URI, withoutTypes
|
||||
}
|
||||
result.packages[k] = v
|
||||
}
|
||||
// Copy the package analysis information.
|
||||
for k, v := range s.actions {
|
||||
if _, ok := withoutTypesIDs[k.pkg.id]; ok {
|
||||
continue
|
||||
}
|
||||
if _, ok := withoutMetadataIDs[k.pkg.id]; ok {
|
||||
continue
|
||||
}
|
||||
result.actions[k] = v
|
||||
}
|
||||
// Copy the package metadata.
|
||||
for k, v := range s.metadata {
|
||||
if _, ok := withoutMetadataIDs[k]; ok {
|
||||
|
Loading…
x
Reference in New Issue
Block a user