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"
|
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) {
|
func (s *snapshot) Analyze(ctx context.Context, id string, analyzers []*analysis.Analyzer) (map[*analysis.Analyzer][]*analysis.Diagnostic, error) {
|
||||||
var roots []*actionHandle
|
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) {
|
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)
|
cph := s.getPackage(id, mode)
|
||||||
if cph == nil {
|
if cph == nil {
|
||||||
return nil, errors.Errorf("no CheckPackageHandle for %s:%v", id, mode == source.ParseExported)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ah := &actionHandle{
|
ah = &actionHandle{
|
||||||
analyzer: a,
|
analyzer: a,
|
||||||
pkg: pkg,
|
pkg: pkg,
|
||||||
}
|
}
|
||||||
@ -118,12 +127,13 @@ func (s *snapshot) actionHandle(ctx context.Context, id packageID, mode source.P
|
|||||||
ah.deps = append(ah.deps, depActionHandle)
|
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 := &actionData{}
|
||||||
data.diagnostics, data.result, data.err = ah.exec(ctx, s.view.session.cache.fset)
|
data.diagnostics, data.result, data.err = ah.exec(ctx, s.view.session.cache.fset)
|
||||||
return data
|
return data
|
||||||
})
|
})
|
||||||
ah.handle = h
|
ah.handle = h
|
||||||
|
s.addAction(ah)
|
||||||
return ah, nil
|
return ah, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +146,7 @@ func (ah *actionHandle) analyze(ctx context.Context) ([]*analysis.Diagnostic, in
|
|||||||
return data.diagnostics, data.result, data.err
|
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))))
|
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{
|
pkg := &pkg{
|
||||||
view: imp.snapshot.view,
|
view: imp.snapshot.view,
|
||||||
id: cph.m.id,
|
id: cph.m.id,
|
||||||
|
mode: cph.mode,
|
||||||
pkgPath: cph.m.pkgPath,
|
pkgPath: cph.m.pkgPath,
|
||||||
files: cph.Files(),
|
files: cph.Files(),
|
||||||
imports: make(map[packagePath]*pkg),
|
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 and package path have their own types to avoid being used interchangeably.
|
||||||
id packageID
|
id packageID
|
||||||
|
mode source.ParseMode
|
||||||
pkgPath packagePath
|
pkgPath packagePath
|
||||||
files []source.ParseGoHandle
|
files []source.ParseGoHandle
|
||||||
errors []packages.Error
|
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),
|
metadata: make(map[packageID]*metadata),
|
||||||
files: make(map[span.URI]source.FileHandle),
|
files: make(map[span.URI]source.FileHandle),
|
||||||
importedBy: make(map[packageID][]packageID),
|
importedBy: make(map[packageID][]packageID),
|
||||||
|
actions: make(map[actionKey]*actionHandle),
|
||||||
},
|
},
|
||||||
ignoredURIs: make(map[span.URI]struct{}),
|
ignoredURIs: make(map[span.URI]struct{}),
|
||||||
builtin: &builtinPkg{},
|
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.
|
// It may invalidated when a file's content changes.
|
||||||
files map[span.URI]source.FileHandle
|
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.
|
// It may be invalidated when a file's content changes.
|
||||||
packages map[packageKey]*checkPackageHandle
|
packages map[packageKey]*checkPackageHandle
|
||||||
|
|
||||||
|
// actions maps an actionkey to its actionHandle.
|
||||||
|
actions map[actionKey]*actionHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *snapshot) View() source.View {
|
func (s *snapshot) View() source.View {
|
||||||
@ -93,6 +96,37 @@ func (s *snapshot) getPackage(id packageID, m source.ParseMode) *checkPackageHan
|
|||||||
return s.packages[key]
|
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) {
|
func (s *snapshot) getMetadataForURI(uri span.URI) (metadata []*metadata) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
@ -175,6 +209,7 @@ func (s *snapshot) clone(ctx context.Context, withoutURI *span.URI, withoutTypes
|
|||||||
importedBy: make(map[packageID][]packageID),
|
importedBy: make(map[packageID][]packageID),
|
||||||
metadata: make(map[packageID]*metadata),
|
metadata: make(map[packageID]*metadata),
|
||||||
packages: make(map[packageKey]*checkPackageHandle),
|
packages: make(map[packageKey]*checkPackageHandle),
|
||||||
|
actions: make(map[actionKey]*actionHandle),
|
||||||
files: make(map[span.URI]source.FileHandle),
|
files: make(map[span.URI]source.FileHandle),
|
||||||
}
|
}
|
||||||
// Copy all of the FileHandles except for the one that was invalidated.
|
// 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
|
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.
|
// Copy the package metadata.
|
||||||
for k, v := range s.metadata {
|
for k, v := range s.metadata {
|
||||||
if _, ok := withoutMetadataIDs[k]; ok {
|
if _, ok := withoutMetadataIDs[k]; ok {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user