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

internal/lsp: rename CheckPackageHandle to PackageHandle

Change-Id: I4ea5fed9fcb71b77da4a15c9d85792bda815ddf5
Reviewed-on: https://go-review.googlesource.com/c/tools/+/209419
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-11-30 01:17:57 -05:00
parent 6e064ea0cf
commit a51b8faf84
19 changed files with 182 additions and 193 deletions

View File

@ -80,14 +80,14 @@ func (s *snapshot) actionHandle(ctx context.Context, id packageID, mode source.P
if act != nil {
return act, nil
}
cph := s.getPackage(id, mode)
if cph == nil {
ph := s.getPackage(id, mode)
if ph == nil {
return nil, errors.Errorf("no CheckPackageHandle for %s:%v", id, mode == source.ParseExported)
}
if len(cph.key) == 0 {
if len(ph.key) == 0 {
return nil, errors.Errorf("no key for CheckPackageHandle %s", id)
}
pkg, err := cph.check(ctx)
pkg, err := ph.check(ctx)
if err != nil {
return nil, err
}
@ -112,8 +112,8 @@ func (s *snapshot) actionHandle(ctx context.Context, id packageID, mode source.P
// An analysis that consumes/produces facts
// must run on the package's dependencies too.
if len(a.FactTypes) > 0 {
importIDs := make([]string, 0, len(cph.m.deps))
for _, importID := range cph.m.deps {
importIDs := make([]string, 0, len(ph.m.deps))
for _, importID := range ph.m.deps {
importIDs = append(importIDs, string(importID))
}
sort.Strings(importIDs) // for determinism
@ -129,7 +129,7 @@ func (s *snapshot) actionHandle(ctx context.Context, id packageID, mode source.P
fset := s.view.session.cache.fset
h := s.view.session.cache.store.Bind(buildActionKey(a, cph), func(ctx context.Context) interface{} {
h := s.view.session.cache.store.Bind(buildActionKey(a, ph), func(ctx context.Context) interface{} {
// Analyze dependencies first.
results, err := execAll(ctx, fset, deps)
if err != nil {
@ -175,8 +175,8 @@ func (act *actionHandle) cached() ([]*source.Error, interface{}, error) {
return data.diagnostics, data.result, data.err
}
func buildActionKey(a *analysis.Analyzer, cph *checkPackageHandle) string {
return hashContents([]byte(fmt.Sprintf("%p %s", a, string(cph.key))))
func buildActionKey(a *analysis.Analyzer, ph *packageHandle) string {
return hashContents([]byte(fmt.Sprintf("%p %s", a, string(ph.key))))
}
func (act *actionHandle) String() string {

View File

@ -24,8 +24,8 @@ import (
errors "golang.org/x/xerrors"
)
// checkPackageHandle implements source.CheckPackageHandle.
type checkPackageHandle struct {
// packageHandle implements source.CheckPackageHandle.
type packageHandle struct {
handle *memoize.Handle
goFiles []source.ParseGoHandle
@ -43,69 +43,69 @@ type checkPackageHandle struct {
key []byte
}
func (cph *checkPackageHandle) packageKey() packageKey {
func (ph *packageHandle) packageKey() packageKey {
return packageKey{
id: cph.m.id,
mode: cph.mode,
id: ph.m.id,
mode: ph.mode,
}
}
// checkPackageData contains the data produced by type-checking a package.
type checkPackageData struct {
// packageData contains the data produced by type-checking a package.
type packageData struct {
memoize.NoCopy
pkg *pkg
err error
}
// checkPackageHandle returns a source.CheckPackageHandle for a given package and config.
func (s *snapshot) checkPackageHandle(ctx context.Context, id packageID, mode source.ParseMode) (*checkPackageHandle, 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) {
// Check if we already have this CheckPackageHandle cached.
if cph := s.getPackage(id, mode); cph != nil {
return cph, nil
if ph := s.getPackage(id, mode); ph != nil {
return ph, nil
}
// Build the CheckPackageHandle for this ID and its dependencies.
cph, deps, err := s.buildKey(ctx, id, mode)
ph, deps, err := s.buildKey(ctx, id, mode)
if err != nil {
return nil, err
}
// Do not close over the checkPackageHandle or the snapshot in the Bind function.
// Do not close over the packageHandle or the snapshot in the Bind function.
// This creates a cycle, which causes the finalizers to never run on the handles.
// The possible cycles are:
//
// checkPackageHandle.h.function -> checkPackageHandle
// checkPackageHandle.h.function -> snapshot -> checkPackageHandle
// packageHandle.h.function -> packageHandle
// packageHandle.h.function -> snapshot -> packageHandle
//
m := cph.m
goFiles := cph.goFiles
compiledGoFiles := cph.compiledGoFiles
key := cph.key
m := ph.m
goFiles := ph.goFiles
compiledGoFiles := ph.compiledGoFiles
key := ph.key
fset := s.view.session.cache.fset
h := s.view.session.cache.store.Bind(string(key), func(ctx context.Context) interface{} {
// Begin loading the direct dependencies, in parallel.
for _, dep := range deps {
go func(dep *checkPackageHandle) {
go func(dep *packageHandle) {
dep.check(ctx)
}(dep)
}
data := &checkPackageData{}
data := &packageData{}
data.pkg, data.err = typeCheck(ctx, fset, m, mode, goFiles, compiledGoFiles, deps)
return data
})
cph.handle = h
ph.handle = h
// Cache the CheckPackageHandle in the snapshot.
s.addPackage(cph)
s.addPackage(ph)
return cph, nil
return ph, nil
}
// buildKey computes the checkPackageKey for a given checkPackageHandle.
func (s *snapshot) buildKey(ctx context.Context, id packageID, mode source.ParseMode) (*checkPackageHandle, map[packagePath]*checkPackageHandle, error) {
func (s *snapshot) buildKey(ctx context.Context, id packageID, mode source.ParseMode) (*packageHandle, map[packagePath]*packageHandle, error) {
m := s.getMetadata(id)
if m == nil {
return nil, nil, errors.Errorf("no metadata for %s", id)
@ -118,7 +118,7 @@ func (s *snapshot) buildKey(ctx context.Context, id packageID, mode source.Parse
if err != nil {
return nil, nil, err
}
cph := &checkPackageHandle{
ph := &packageHandle{
m: m,
goFiles: goFiles,
compiledGoFiles: compiledGoFiles,
@ -131,12 +131,12 @@ func (s *snapshot) buildKey(ctx context.Context, id packageID, mode source.Parse
return depList[i] < depList[j]
})
deps := make(map[packagePath]*checkPackageHandle)
deps := make(map[packagePath]*packageHandle)
// Begin computing the key by getting the depKeys for all dependencies.
var depKeys [][]byte
for _, depID := range depList {
depHandle, err := s.checkPackageHandle(ctx, depID, source.ParseExported)
depHandle, err := s.packageHandle(ctx, depID, source.ParseExported)
if err != nil {
log.Error(ctx, "no dep handle", err, telemetry.Package.Of(depID))
@ -148,12 +148,12 @@ func (s *snapshot) buildKey(ctx context.Context, id packageID, mode source.Parse
deps[depHandle.m.pkgPath] = depHandle
depKeys = append(depKeys, depHandle.key)
}
cph.key = checkPackageKey(cph.m.id, cph.compiledGoFiles, m.config, depKeys)
return cph, deps, nil
ph.key = checkPackageKey(ph.m.id, ph.compiledGoFiles, m.config, depKeys)
return ph, deps, nil
}
func checkPackageKey(id packageID, phs []source.ParseGoHandle, cfg *packages.Config, deps [][]byte) []byte {
return []byte(hashContents([]byte(fmt.Sprintf("%s%s%s%s", id, hashParseKeys(phs), hashConfig(cfg), hashContents(bytes.Join(deps, nil))))))
func checkPackageKey(id packageID, pghs []source.ParseGoHandle, cfg *packages.Config, deps [][]byte) []byte {
return []byte(hashContents([]byte(fmt.Sprintf("%s%s%s%s", id, hashParseKeys(pghs), hashConfig(cfg), hashContents(bytes.Join(deps, nil))))))
}
// hashConfig returns the hash for the *packages.Config.
@ -173,45 +173,45 @@ func hashConfig(config *packages.Config) string {
return hashContents(b.Bytes())
}
func (cph *checkPackageHandle) Check(ctx context.Context) (source.Package, error) {
return cph.check(ctx)
func (ph *packageHandle) Check(ctx context.Context) (source.Package, error) {
return ph.check(ctx)
}
func (cph *checkPackageHandle) check(ctx context.Context) (*pkg, error) {
v := cph.handle.Get(ctx)
func (ph *packageHandle) check(ctx context.Context) (*pkg, error) {
v := ph.handle.Get(ctx)
if v == nil {
return nil, errors.Errorf("no package for %s", cph.m.id)
return nil, errors.Errorf("no package for %s", ph.m.id)
}
data := v.(*checkPackageData)
data := v.(*packageData)
return data.pkg, data.err
}
func (cph *checkPackageHandle) CompiledGoFiles() []source.ParseGoHandle {
return cph.compiledGoFiles
func (ph *packageHandle) CompiledGoFiles() []source.ParseGoHandle {
return ph.compiledGoFiles
}
func (cph *checkPackageHandle) ID() string {
return string(cph.m.id)
func (ph *packageHandle) ID() string {
return string(ph.m.id)
}
func (cph *checkPackageHandle) MissingDependencies() []string {
func (ph *packageHandle) MissingDependencies() []string {
var md []string
for i := range cph.m.missingDeps {
for i := range ph.m.missingDeps {
md = append(md, string(i))
}
return md
}
func (cph *checkPackageHandle) Cached() (source.Package, error) {
return cph.cached()
func (ph *packageHandle) Cached() (source.Package, error) {
return ph.cached()
}
func (cph *checkPackageHandle) cached() (*pkg, error) {
v := cph.handle.Cached()
func (ph *packageHandle) cached() (*pkg, error) {
v := ph.handle.Cached()
if v == nil {
return nil, errors.Errorf("no cached type information for %s", cph.m.pkgPath)
return nil, errors.Errorf("no cached type information for %s", ph.m.pkgPath)
}
data := v.(*checkPackageData)
data := v.(*packageData)
return data.pkg, data.err
}
@ -228,7 +228,7 @@ func (s *snapshot) parseGoHandles(ctx context.Context, files []span.URI, mode so
return phs, nil
}
func typeCheck(ctx context.Context, fset *token.FileSet, m *metadata, mode source.ParseMode, goFiles []source.ParseGoHandle, compiledGoFiles []source.ParseGoHandle, deps map[packagePath]*checkPackageHandle) (*pkg, error) {
func typeCheck(ctx context.Context, fset *token.FileSet, m *metadata, mode source.ParseMode, goFiles []source.ParseGoHandle, compiledGoFiles []source.ParseGoHandle, deps map[packagePath]*packageHandle) (*pkg, error) {
ctx, done := trace.StartSpan(ctx, "cache.importer.typeCheck", telemetry.Package.Of(m.id))
defer done()

View File

@ -76,20 +76,20 @@ func (s *session) Cache() source.Cache {
return s.cache
}
func (s *session) NewView(ctx context.Context, name string, folder span.URI, options source.Options) (source.View, []source.CheckPackageHandle, error) {
func (s *session) NewView(ctx context.Context, name string, folder span.URI, options source.Options) (source.View, []source.PackageHandle, error) {
s.viewMu.Lock()
defer s.viewMu.Unlock()
v, cphs, err := s.createView(ctx, name, folder, options)
v, phs, err := s.createView(ctx, name, folder, options)
if err != nil {
return nil, nil, err
}
s.views = append(s.views, v)
// we always need to drop the view map
s.viewMap = make(map[span.URI]source.View)
return v, cphs, nil
return v, phs, nil
}
func (s *session) createView(ctx context.Context, name string, folder span.URI, options source.Options) (*view, []source.CheckPackageHandle, error) {
func (s *session) createView(ctx context.Context, name string, folder span.URI, options source.Options) (*view, []source.PackageHandle, error) {
index := atomic.AddInt64(&viewIndex, 1)
// We want a true background context and not a detached context here
// the spans need to be unrelated and no tag values should pollute it.
@ -107,7 +107,7 @@ func (s *session) createView(ctx context.Context, name string, folder span.URI,
filesByURI: make(map[span.URI]viewFile),
filesByBase: make(map[string][]viewFile),
snapshot: &snapshot{
packages: make(map[packageKey]*checkPackageHandle),
packages: make(map[packageKey]*packageHandle),
ids: make(map[span.URI][]packageID),
metadata: make(map[packageID]*metadata),
files: make(map[span.URI]source.FileHandle),
@ -144,13 +144,13 @@ func (s *session) createView(ctx context.Context, name string, folder span.URI,
// Prepare CheckPackageHandles for every package that's been loaded.
// (*snapshot).CheckPackageHandle makes the assumption that every package that's
// been loaded has an existing checkPackageHandle.
cphs, err := v.snapshot.checkWorkspacePackages(ctx, m)
phs, err := v.snapshot.checkWorkspacePackages(ctx, m)
if err != nil {
return nil, nil, err
}
debug.AddView(debugView{v})
return v, cphs, loadErr
return v, phs, loadErr
}
// View returns the view by name.
@ -245,14 +245,14 @@ func (s *session) removeView(ctx context.Context, view *view) error {
return nil
}
func (s *session) updateView(ctx context.Context, view *view, options source.Options) (*view, []source.CheckPackageHandle, error) {
func (s *session) updateView(ctx context.Context, view *view, options source.Options) (*view, []source.PackageHandle, error) {
s.viewMu.Lock()
defer s.viewMu.Unlock()
i, err := s.dropView(ctx, view)
if err != nil {
return nil, nil, err
}
v, cphs, err := s.createView(ctx, view.name, view.folder, options)
v, phs, err := s.createView(ctx, view.name, view.folder, options)
if err != nil {
// we have dropped the old view, but could not create the new one
// this should not happen and is very bad, but we still need to clean
@ -263,7 +263,7 @@ func (s *session) updateView(ctx context.Context, view *view, options source.Opt
}
// substitute the new view into the array where the old view was
s.views[i] = v
return v, cphs, nil
return v, phs, nil
}
func (s *session) dropView(ctx context.Context, view *view) (int, error) {

View File

@ -37,7 +37,7 @@ type snapshot struct {
// 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
packages map[packageKey]*packageHandle
// actions maps an actionkey to its actionHandle.
actions map[actionKey]*actionHandle
@ -61,13 +61,13 @@ func (s *snapshot) View() source.View {
return s.view
}
func (s *snapshot) PackageHandles(ctx context.Context, fh source.FileHandle) ([]source.CheckPackageHandle, error) {
func (s *snapshot) PackageHandles(ctx context.Context, fh source.FileHandle) ([]source.PackageHandle, error) {
ctx = telemetry.File.With(ctx, fh.Identity().URI)
metadata := s.getMetadataForURI(fh.Identity().URI)
// Determine if we need to type-check the package.
cphs, load, check := s.shouldCheck(metadata)
phs, load, check := s.shouldCheck(metadata)
// We may need to re-load package metadata.
// We only need to this if it has been invalidated, and is therefore unvailable.
@ -83,23 +83,23 @@ func (s *snapshot) PackageHandles(ctx context.Context, fh source.FileHandle) ([]
}
}
if check {
var results []source.CheckPackageHandle
var results []source.PackageHandle
for _, m := range metadata {
cph, err := s.checkPackageHandle(ctx, m.id, source.ParseFull)
ph, err := s.packageHandle(ctx, m.id, source.ParseFull)
if err != nil {
return nil, err
}
results = append(results, cph)
results = append(results, ph)
}
cphs = results
phs = results
}
if len(cphs) == 0 {
if len(phs) == 0 {
return nil, errors.Errorf("no CheckPackageHandles for %s", fh.Identity().URI)
}
return cphs, nil
return phs, nil
}
func (s *snapshot) PackageHandle(ctx context.Context, id string) (source.CheckPackageHandle, error) {
func (s *snapshot) PackageHandle(ctx context.Context, id string) (source.PackageHandle, error) {
ctx = telemetry.Package.With(ctx, id)
m := s.getMetadata(packageID(id))
@ -107,25 +107,25 @@ func (s *snapshot) PackageHandle(ctx context.Context, id string) (source.CheckPa
return nil, errors.Errorf("no known metadata for %s", id)
}
// Determine if we need to type-check the package.
cphs, load, check := s.shouldCheck([]*metadata{m})
phs, load, check := s.shouldCheck([]*metadata{m})
if load {
return nil, errors.Errorf("outdated metadata for %s, needs re-load", id)
}
if check {
return s.checkPackageHandle(ctx, m.id, source.ParseFull)
return s.packageHandle(ctx, m.id, source.ParseFull)
}
if len(cphs) == 0 {
if len(phs) == 0 {
return nil, errors.Errorf("no check package handle for %s", id)
}
if len(cphs) > 1 {
if len(phs) > 1 {
return nil, errors.Errorf("multiple check package handles for a single id: %s", id)
}
return cphs[0], nil
return phs[0], nil
}
// shouldCheck determines if the packages provided by the metadata
// need to be re-loaded or re-type-checked.
func (s *snapshot) shouldCheck(m []*metadata) (cphs []source.CheckPackageHandle, load, check bool) {
func (s *snapshot) shouldCheck(m []*metadata) (phs []source.PackageHandle, load, check bool) {
// No metadata. Re-load and re-check.
if len(m) == 0 {
return nil, true, true
@ -135,23 +135,23 @@ func (s *snapshot) shouldCheck(m []*metadata) (cphs []source.CheckPackageHandle,
// If a single CheckPackageHandle is missing, re-check all of them.
// TODO: Optimize this by only checking the necessary packages.
for _, metadata := range m {
cph := s.getPackage(metadata.id, source.ParseFull)
if cph == nil {
ph := s.getPackage(metadata.id, source.ParseFull)
if ph == nil {
return nil, false, true
}
cphs = append(cphs, cph)
phs = append(phs, ph)
}
// If the metadata for the package had missing dependencies,
// we _may_ need to re-check. If the missing dependencies haven't changed
// since previous load, we will not check again.
if len(cphs) < len(m) {
if len(phs) < len(m) {
for _, m := range m {
if len(m.missingDeps) != 0 {
return nil, true, true
}
}
}
return cphs, false, false
return phs, false, false
}
func (s *snapshot) GetReverseDependencies(id string) []string {
@ -197,34 +197,34 @@ func (s *snapshot) getImportedBy(id packageID) []packageID {
return s.importedBy[id]
}
func (s *snapshot) addPackage(cph *checkPackageHandle) {
func (s *snapshot) addPackage(ph *packageHandle) {
s.mu.Lock()
defer s.mu.Unlock()
// TODO: We should make sure not to compute duplicate CheckPackageHandles,
// and instead panic here. This will be hard to do because we may encounter
// the same package multiple times in the dependency tree.
if _, ok := s.packages[cph.packageKey()]; ok {
if _, ok := s.packages[ph.packageKey()]; ok {
return
}
s.packages[cph.packageKey()] = cph
s.packages[ph.packageKey()] = ph
}
// checkWorkspacePackages checks the initial set of packages loaded when
// the view is created. This is needed because
// (*snapshot).CheckPackageHandle makes the assumption that every package that's
// been loaded has an existing checkPackageHandle.
func (s *snapshot) checkWorkspacePackages(ctx context.Context, m []*metadata) ([]source.CheckPackageHandle, error) {
var cphs []source.CheckPackageHandle
func (s *snapshot) checkWorkspacePackages(ctx context.Context, m []*metadata) ([]source.PackageHandle, error) {
var phs []source.PackageHandle
for _, m := range m {
cph, err := s.checkPackageHandle(ctx, m.id, source.ParseFull)
ph, err := s.packageHandle(ctx, m.id, source.ParseFull)
if err != nil {
return nil, err
}
s.workspacePackages[m.id] = true
cphs = append(cphs, cph)
phs = append(phs, ph)
}
return cphs, nil
return phs, nil
}
func (s *snapshot) KnownPackages(ctx context.Context) []source.Package {
@ -251,14 +251,14 @@ func (s *snapshot) KnownPackages(ctx context.Context) []source.Package {
// Any package in our workspace should be loaded with ParseFull.
mode = source.ParseFull
}
cph, err := s.checkPackageHandle(ctx, pkgID, mode)
ph, err := s.packageHandle(ctx, pkgID, mode)
if err != nil {
log.Error(ctx, "failed to create CheckPackageHandle", err, telemetry.Package.Of(pkgID))
continue
}
// Check the package now if it's not checked yet.
// TODO(matloob): is this too slow?
pkg, err := cph.check(ctx)
pkg, err := ph.check(ctx)
if err != nil {
log.Error(ctx, "failed to check package", err, telemetry.Package.Of(pkgID))
continue
@ -274,8 +274,8 @@ func (s *snapshot) KnownImportPaths() map[string]source.Package {
defer s.mu.Unlock()
results := map[string]source.Package{}
for _, cph := range s.packages {
cachedPkg, err := cph.cached()
for _, ph := range s.packages {
cachedPkg, err := ph.cached()
if err != nil {
continue
}
@ -293,7 +293,7 @@ func (s *snapshot) KnownImportPaths() map[string]source.Package {
return results
}
func (s *snapshot) getPackage(id packageID, m source.ParseMode) *checkPackageHandle {
func (s *snapshot) getPackage(id packageID, m source.ParseMode) *packageHandle {
s.mu.Lock()
defer s.mu.Unlock()
@ -418,7 +418,7 @@ func (s *snapshot) clone(ctx context.Context, withoutURI span.URI, withoutTypes,
ids: make(map[span.URI][]packageID),
importedBy: make(map[packageID][]packageID),
metadata: make(map[packageID]*metadata),
packages: make(map[packageKey]*checkPackageHandle),
packages: make(map[packageKey]*packageHandle),
actions: make(map[actionKey]*actionHandle),
files: make(map[span.URI]source.FileHandle),
workspacePackages: make(map[packageID]bool),

View File

@ -207,20 +207,20 @@ func quickFixes(ctx context.Context, snapshot source.Snapshot, f source.File, di
var codeActions []protocol.CodeAction
fh := snapshot.Handle(ctx, f)
cphs, err := snapshot.PackageHandles(ctx, fh)
phs, err := snapshot.PackageHandles(ctx, fh)
if err != nil {
return nil, err
}
// We get the package that source.Diagnostics would've used. This is hack.
// TODO(golang/go#32443): The correct solution will be to cache diagnostics per-file per-snapshot.
cph, err := source.WidestCheckPackageHandle(cphs)
ph, err := source.WidestCheckPackageHandle(phs)
if err != nil {
return nil, err
}
for _, diag := range diagnostics {
// This code assumes that the analyzer name is the Source of the diagnostic.
// If this ever changes, this will need to be addressed.
srcErr, err := snapshot.FindAnalysisError(ctx, cph.ID(), diag.Source, diag.Message, diag.Range)
srcErr, err := snapshot.FindAnalysisError(ctx, ph.ID(), diag.Source, diag.Message, diag.Range)
if err != nil {
continue
}

View File

@ -16,17 +16,17 @@ import (
"golang.org/x/tools/internal/telemetry/trace"
)
func (s *Server) diagnoseSnapshot(snapshot source.Snapshot, cphs []source.CheckPackageHandle) {
func (s *Server) diagnoseSnapshot(snapshot source.Snapshot, phs []source.PackageHandle) {
ctx := snapshot.View().BackgroundContext()
ctx, done := trace.StartSpan(ctx, "lsp:background-worker")
defer done()
for _, cph := range cphs {
if len(cph.CompiledGoFiles()) == 0 {
for _, ph := range phs {
if len(ph.CompiledGoFiles()) == 0 {
continue
}
// Find a file on which to call diagnostics.
uri := cph.CompiledGoFiles()[0].File().Identity().URI
uri := ph.CompiledGoFiles()[0].File().Identity().URI
f, err := snapshot.View().GetFile(ctx, uri)
if err != nil {
log.Error(ctx, "no file", err, telemetry.URI.Of(uri))

View File

@ -395,23 +395,23 @@ func Completion(ctx context.Context, snapshot Snapshot, f File, pos protocol.Pos
startTime := time.Now()
fh := snapshot.Handle(ctx, f)
cphs, err := snapshot.PackageHandles(ctx, fh)
phs, err := snapshot.PackageHandles(ctx, fh)
if err != nil {
return nil, nil, err
}
cph, err := NarrowestCheckPackageHandle(cphs)
ph, err := NarrowestCheckPackageHandle(phs)
if err != nil {
return nil, nil, err
}
pkg, err := cph.Check(ctx)
pkg, err := ph.Check(ctx)
if err != nil {
return nil, nil, err
}
ph, err := pkg.File(f.URI())
pgh, err := pkg.File(f.URI())
if err != nil {
return nil, nil, err
}
file, m, _, err := ph.Cached()
file, m, _, err := pgh.Cached()
if err != nil {
return nil, nil, err
}

View File

@ -44,24 +44,24 @@ func Diagnostics(ctx context.Context, snapshot Snapshot, f File, withAnalysis bo
defer done()
fh := snapshot.Handle(ctx, f)
cphs, err := snapshot.PackageHandles(ctx, fh)
phs, err := snapshot.PackageHandles(ctx, fh)
if err != nil {
return nil, "", err
}
cph, err := WidestCheckPackageHandle(cphs)
ph, err := WidestCheckPackageHandle(phs)
if err != nil {
return nil, "", err
}
// If we are missing dependencies, it may because the user's workspace is
// not correctly configured. Report errors, if possible.
var warningMsg string
if len(cph.MissingDependencies()) > 0 {
if len(ph.MissingDependencies()) > 0 {
warningMsg, err = checkCommonErrors(ctx, snapshot.View(), f.URI())
if err != nil {
log.Error(ctx, "error checking common errors", err, telemetry.File.Of(f.URI))
}
}
pkg, err := cph.Check(ctx)
pkg, err := ph.Check(ctx)
if err != nil {
log.Error(ctx, "no package for file", err)
return singleDiagnostic(fh.Identity(), "%s is not part of a package", f.URI()), "", nil
@ -81,17 +81,17 @@ func Diagnostics(ctx context.Context, snapshot Snapshot, f File, withAnalysis bo
// Run diagnostics for the package that this URI belongs to.
if !diagnostics(ctx, snapshot, pkg, reports) && withAnalysis {
// If we don't have any list, parse, or type errors, run analyses.
if err := analyses(ctx, snapshot, cph, disabledAnalyses, reports); err != nil {
if err := analyses(ctx, snapshot, ph, disabledAnalyses, reports); err != nil {
log.Error(ctx, "failed to run analyses", err, telemetry.File.Of(f.URI()))
}
}
// Updates to the diagnostics for this package may need to be propagated.
for _, id := range snapshot.GetReverseDependencies(pkg.ID()) {
cph, err := snapshot.PackageHandle(ctx, id)
ph, err := snapshot.PackageHandle(ctx, id)
if err != nil {
return nil, warningMsg, err
}
pkg, err := cph.Check(ctx)
pkg, err := ph.Check(ctx)
if err != nil {
return nil, warningMsg, err
}
@ -153,7 +153,7 @@ func diagnostics(ctx context.Context, snapshot Snapshot, pkg Package, reports ma
return nonEmptyDiagnostics
}
func analyses(ctx context.Context, snapshot Snapshot, cph CheckPackageHandle, disabledAnalyses map[string]struct{}, reports map[FileIdentity][]Diagnostic) error {
func analyses(ctx context.Context, snapshot Snapshot, ph PackageHandle, disabledAnalyses map[string]struct{}, reports map[FileIdentity][]Diagnostic) error {
var analyzers []*analysis.Analyzer
for _, a := range snapshot.View().Options().Analyzers {
if _, ok := disabledAnalyses[a.Name]; ok {
@ -162,7 +162,7 @@ func analyses(ctx context.Context, snapshot Snapshot, cph CheckPackageHandle, di
analyzers = append(analyzers, a)
}
diagnostics, err := snapshot.Analyze(ctx, cph.ID(), analyzers)
diagnostics, err := snapshot.Analyze(ctx, ph.ID(), analyzers)
if err != nil {
return err
}

View File

@ -19,8 +19,8 @@ func FoldingRange(ctx context.Context, snapshot Snapshot, f File, lineFoldingOnl
// TODO(suzmue): consider limiting the number of folding ranges returned, and
// implement a way to prioritize folding ranges in that case.
fh := snapshot.Handle(ctx, f)
ph := snapshot.View().Session().Cache().ParseGoHandle(fh, ParseFull)
file, m, _, err := ph.Parse(ctx)
pgh := snapshot.View().Session().Cache().ParseGoHandle(fh, ParseFull)
file, m, _, err := pgh.Parse(ctx)
if err != nil {
return nil, err
}

View File

@ -28,28 +28,28 @@ func Format(ctx context.Context, snapshot Snapshot, f File) ([]protocol.TextEdit
defer done()
fh := snapshot.Handle(ctx, f)
cphs, err := snapshot.PackageHandles(ctx, fh)
phs, err := snapshot.PackageHandles(ctx, fh)
if err != nil {
return nil, err
}
cph, err := NarrowestCheckPackageHandle(cphs)
ph, err := NarrowestCheckPackageHandle(phs)
if err != nil {
return nil, err
}
pkg, err := cph.Check(ctx)
pkg, err := ph.Check(ctx)
if err != nil {
return nil, err
}
ph, err := pkg.File(f.URI())
pgh, err := pkg.File(f.URI())
if err != nil {
return nil, err
}
// Be extra careful that the file's ParseMode is correct,
// otherwise we might replace the user's code with a trimmed AST.
if ph.Mode() != ParseFull {
return nil, errors.Errorf("%s was parsed in the incorrect mode", ph.File().Identity().URI)
if pgh.Mode() != ParseFull {
return nil, errors.Errorf("%s was parsed in the incorrect mode", pgh.File().Identity().URI)
}
file, m, _, err := ph.Parse(ctx)
file, m, _, err := pgh.Parse(ctx)
if err != nil {
return nil, err
}
@ -62,7 +62,7 @@ func Format(ctx context.Context, snapshot Snapshot, f File) ([]protocol.TextEdit
if err != nil {
return nil, err
}
return computeTextEdits(ctx, snapshot.View(), ph.File(), m, string(formatted))
return computeTextEdits(ctx, snapshot.View(), pgh.File(), m, string(formatted))
}
fset := snapshot.View().Session().Cache().FileSet()
@ -75,7 +75,7 @@ func Format(ctx context.Context, snapshot Snapshot, f File) ([]protocol.TextEdit
if err := format.Node(buf, fset, file); err != nil {
return nil, err
}
return computeTextEdits(ctx, snapshot.View(), ph.File(), m, buf.String())
return computeTextEdits(ctx, snapshot.View(), pgh.File(), m, buf.String())
}
func formatSource(ctx context.Context, s Snapshot, f File) ([]byte, error) {
@ -103,31 +103,25 @@ func AllImportsFixes(ctx context.Context, snapshot Snapshot, f File) (allFixEdit
defer done()
fh := snapshot.Handle(ctx, f)
cphs, err := snapshot.PackageHandles(ctx, fh)
phs, err := snapshot.PackageHandles(ctx, fh)
if err != nil {
return nil, nil, err
}
cph, err := NarrowestCheckPackageHandle(cphs)
ph, err := NarrowestCheckPackageHandle(phs)
if err != nil {
return nil, nil, err
}
pkg, err := cph.Check(ctx)
pkg, err := ph.Check(ctx)
if err != nil {
return nil, nil, err
}
if hasListErrors(pkg) {
return nil, nil, errors.Errorf("%s has list errors, not running goimports", f.URI())
}
var ph ParseGoHandle
for _, h := range pkg.CompiledGoFiles() {
if h.File().Identity().URI == f.URI() {
ph = h
}
pgh, err := pkg.File(f.URI())
if err != nil {
return nil, nil, err
}
if ph == nil {
return nil, nil, errors.Errorf("no ParseGoHandle for %s", f.URI())
}
options := &imports.Options{
// Defaults.
AllErrors: true,
@ -138,7 +132,7 @@ func AllImportsFixes(ctx context.Context, snapshot Snapshot, f File) (allFixEdit
TabWidth: 8,
}
err = snapshot.View().RunProcessEnvFunc(ctx, func(opts *imports.Options) error {
allFixEdits, editsPerFix, err = computeImportEdits(ctx, snapshot.View(), ph, opts)
allFixEdits, editsPerFix, err = computeImportEdits(ctx, snapshot.View(), pgh, opts)
return err
}, options)
if err != nil {

View File

@ -20,28 +20,23 @@ func Highlight(ctx context.Context, snapshot Snapshot, f File, pos protocol.Posi
defer done()
fh := snapshot.Handle(ctx, f)
cphs, err := snapshot.PackageHandles(ctx, fh)
phs, err := snapshot.PackageHandles(ctx, fh)
if err != nil {
return nil, err
}
cph, err := WidestCheckPackageHandle(cphs)
ph, err := WidestCheckPackageHandle(phs)
if err != nil {
return nil, err
}
pkg, err := cph.Check(ctx)
pkg, err := ph.Check(ctx)
if err != nil {
return nil, err
}
var ph ParseGoHandle
for _, file := range pkg.CompiledGoFiles() {
if file.File().Identity().URI == f.URI() {
ph = file
}
pgh, err := pkg.File(f.URI())
if err != nil {
return nil, err
}
if ph == nil {
return nil, errors.Errorf("no ParseGoHandle for %s", f.URI())
}
file, m, _, err := ph.Parse(ctx)
file, m, _, err := pgh.Parse(ctx)
if err != nil {
return nil, err
}

View File

@ -51,23 +51,23 @@ func Identifier(ctx context.Context, snapshot Snapshot, f File, pos protocol.Pos
defer done()
fh := snapshot.Handle(ctx, f)
cphs, err := snapshot.PackageHandles(ctx, fh)
phs, err := snapshot.PackageHandles(ctx, fh)
if err != nil {
return nil, err
}
cph, err := WidestCheckPackageHandle(cphs)
ph, err := WidestCheckPackageHandle(phs)
if err != nil {
return nil, err
}
pkg, err := cph.Check(ctx)
pkg, err := ph.Check(ctx)
if err != nil {
return nil, err
}
ph, err := pkg.File(f.URI())
pgh, err := pkg.File(f.URI())
if err != nil {
return nil, err
}
file, m, _, err := ph.Cached()
file, m, _, err := pgh.Cached()
if err != nil {
return nil, err
}

View File

@ -76,12 +76,12 @@ func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, erro
if i.Declaration.obj.Exported() {
// Only search all packages if the identifier is exported.
for _, id := range i.Snapshot.GetReverseDependencies(i.pkg.ID()) {
cph, err := i.Snapshot.PackageHandle(ctx, id)
ph, err := i.Snapshot.PackageHandle(ctx, id)
if err != nil {
log.Error(ctx, "References: no CheckPackageHandle", err, telemetry.Package.Of(id))
continue
}
pkg, err := cph.Check(ctx)
pkg, err := ph.Check(ctx)
if err != nil {
log.Error(ctx, "References: no Package", err, telemetry.Package.Of(id))
continue

View File

@ -32,23 +32,23 @@ func SignatureHelp(ctx context.Context, snapshot Snapshot, f File, pos protocol.
defer done()
fh := snapshot.Handle(ctx, f)
cphs, err := snapshot.PackageHandles(ctx, fh)
phs, err := snapshot.PackageHandles(ctx, fh)
if err != nil {
return nil, err
}
cph, err := NarrowestCheckPackageHandle(cphs)
ph, err := NarrowestCheckPackageHandle(phs)
if err != nil {
return nil, err
}
pkg, err := cph.Check(ctx)
pkg, err := ph.Check(ctx)
if err != nil {
return nil, err
}
ph, err := pkg.File(f.URI())
pgh, err := pkg.File(f.URI())
if err != nil {
return nil, err
}
file, m, _, err := ph.Cached()
file, m, _, err := pgh.Cached()
if err != nil {
return nil, err
}

View File

@ -19,23 +19,23 @@ func DocumentSymbols(ctx context.Context, snapshot Snapshot, f File) ([]protocol
defer done()
fh := snapshot.Handle(ctx, f)
cphs, err := snapshot.PackageHandles(ctx, fh)
phs, err := snapshot.PackageHandles(ctx, fh)
if err != nil {
return nil, err
}
cph, err := NarrowestCheckPackageHandle(cphs)
ph, err := NarrowestCheckPackageHandle(phs)
if err != nil {
return nil, err
}
pkg, err := cph.Check(ctx)
pkg, err := ph.Check(ctx)
if err != nil {
return nil, err
}
ph, err := pkg.File(f.URI())
pgh, err := pkg.File(f.URI())
if err != nil {
return nil, err
}
file, m, _, err := ph.Cached()
file, m, _, err := pgh.Cached()
if err != nil {
return nil, err
}

View File

@ -70,7 +70,7 @@ func (s mappedRange) URI() span.URI {
// By "narrowest" package, we mean the package with the fewest number of files
// that includes the given file. This solves the problem of test variants,
// as the test will have more files than the non-test package.
func NarrowestCheckPackageHandle(handles []CheckPackageHandle) (CheckPackageHandle, error) {
func NarrowestCheckPackageHandle(handles []PackageHandle) (PackageHandle, error) {
if len(handles) < 1 {
return nil, errors.Errorf("no CheckPackageHandles")
}
@ -90,7 +90,7 @@ func NarrowestCheckPackageHandle(handles []CheckPackageHandle) (CheckPackageHand
//
// This is useful for something like diagnostics, where we'd prefer to offer diagnostics
// for as many files as possible.
func WidestCheckPackageHandle(handles []CheckPackageHandle) (CheckPackageHandle, error) {
func WidestCheckPackageHandle(handles []PackageHandle) (PackageHandle, error) {
if len(handles) < 1 {
return nil, errors.Errorf("no CheckPackageHandles")
}

View File

@ -34,11 +34,11 @@ type Snapshot interface {
FindAnalysisError(ctx context.Context, pkgID, analyzerName, msg string, rng protocol.Range) (*Error, error)
// PackageHandle returns the CheckPackageHandle for the given package ID.
PackageHandle(ctx context.Context, id string) (CheckPackageHandle, error)
PackageHandle(ctx context.Context, id string) (PackageHandle, error)
// PackageHandles returns the CheckPackageHandles for the packages
// that this file belongs to.
PackageHandles(ctx context.Context, fh FileHandle) ([]CheckPackageHandle, error)
PackageHandles(ctx context.Context, fh FileHandle) ([]PackageHandle, error)
// GetActiveReverseDeps returns the active files belonging to the reverse
// dependencies of this file's package.
@ -52,13 +52,13 @@ type Snapshot interface {
KnownPackages(ctx context.Context) []Package
}
// CheckPackageHandle represents a handle to a specific version of a package.
// PackageHandle represents a handle to a specific version of a package.
// It is uniquely defined by the file handles that make up the package.
type CheckPackageHandle interface {
type PackageHandle interface {
// ID returns the ID of the package associated with the CheckPackageHandle.
ID() string
// ParseGoHandle returns a ParseGoHandle for which to get the package.
// CompiledGoFiles returns the ParseGoHandles composing the package.
CompiledGoFiles() []ParseGoHandle
// Check returns the type-checked Package for the CheckPackageHandle.
@ -140,7 +140,7 @@ type View interface {
// A session may have many active views at any given time.
type Session interface {
// NewView creates a new View and returns it.
NewView(ctx context.Context, name string, folder span.URI, options Options) (View, []CheckPackageHandle, error)
NewView(ctx context.Context, name string, folder span.URI, options Options) (View, []PackageHandle, error)
// Cache returns the cache that created this session.
Cache() Cache

View File

@ -44,12 +44,12 @@ func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.Did
}
snapshot := view.Snapshot()
fh := snapshot.Handle(ctx, f)
cphs, err := snapshot.PackageHandles(ctx, fh)
phs, err := snapshot.PackageHandles(ctx, fh)
if err != nil {
log.Error(ctx, "didChangeWatchedFiles: CheckPackageHandles", err, telemetry.File)
continue
}
cph, err := source.WidestCheckPackageHandle(cphs)
ph, err := source.WidestCheckPackageHandle(phs)
if err != nil {
log.Error(ctx, "didChangeWatchedFiles: WidestCheckPackageHandle", err, telemetry.File)
continue
@ -57,11 +57,11 @@ func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.Did
// Find a different file in the same package we can use to trigger diagnostics.
// TODO(rstambler): Allow diagnostics to be called per-package to avoid this.
var otherFile source.File
for _, ph := range cph.CompiledGoFiles() {
if ph.File().Identity().URI == f.URI() {
for _, pgh := range ph.CompiledGoFiles() {
if pgh.File().Identity().URI == f.URI() {
continue
}
if f := view.FindFile(ctx, ph.File().Identity().URI); f != nil && s.session.IsOpen(f.URI()) {
if f := view.FindFile(ctx, pgh.File().Identity().URI); f != nil && s.session.IsOpen(f.URI()) {
otherFile = f
break
}

View File

@ -26,7 +26,7 @@ func (s *Server) changeFolders(ctx context.Context, event protocol.WorkspaceFold
return nil
}
func (s *Server) addView(ctx context.Context, name string, uri span.URI) (source.View, []source.CheckPackageHandle, error) {
func (s *Server) addView(ctx context.Context, name string, uri span.URI) (source.View, []source.PackageHandle, error) {
s.stateMu.Lock()
state := s.state
s.stateMu.Unlock()