internal/lsp: key GC details off package ID
Rather than using the directory of the package, store the package ID and
calculate the directory in GCOptimizationDetails. I think this is
slightly more readable/cleaner.
Change-Id: I13cac8a7552b73b2bd5d25ff582b5d4936a74827
Reviewed-on: https://go-review.googlesource.com/c/tools/+/297877
Trust: Heschi Kreinick <heschi@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/internal/lsp/command.go b/internal/lsp/command.go
index edcff12..1960270 100644
--- a/internal/lsp/command.go
+++ b/internal/lsp/command.go
@@ -613,13 +613,16 @@
progress: "Toggling GC Details",
forURI: args.URI,
}, func(ctx context.Context, deps commandDeps) error {
- pkgDir := span.URIFromPath(filepath.Dir(args.URI.SpanURI().Filename()))
+ pkg, err := deps.snapshot.PackageForFile(ctx, deps.fh.URI(), source.TypecheckWorkspace, source.NarrowestPackage)
+ if err != nil {
+ return err
+ }
c.s.gcOptimizationDetailsMu.Lock()
- if _, ok := c.s.gcOptimizationDetails[pkgDir]; ok {
- delete(c.s.gcOptimizationDetails, pkgDir)
+ if _, ok := c.s.gcOptimizationDetails[pkg.ID()]; ok {
+ delete(c.s.gcOptimizationDetails, pkg.ID())
c.s.clearDiagnosticSource(gcDetailsSource)
} else {
- c.s.gcOptimizationDetails[pkgDir] = struct{}{}
+ c.s.gcOptimizationDetails[pkg.ID()] = struct{}{}
}
c.s.gcOptimizationDetailsMu.Unlock()
c.s.diagnoseSnapshot(deps.snapshot, nil, false)
diff --git a/internal/lsp/diagnostics.go b/internal/lsp/diagnostics.go
index 479d948..8b93058 100644
--- a/internal/lsp/diagnostics.go
+++ b/internal/lsp/diagnostics.go
@@ -246,20 +246,8 @@
ctx, done := event.Start(ctx, "Server.diagnosePkg", tag.Snapshot.Of(snapshot.ID()), tag.Package.Of(pkg.ID()))
defer done()
includeAnalysis := alwaysAnalyze // only run analyses for packages with open files
- var gcDetailsDir span.URI // find the package's optimization details, if available
for _, pgf := range pkg.CompiledGoFiles() {
- if snapshot.IsOpen(pgf.URI) {
- includeAnalysis = true
- }
- if gcDetailsDir == "" {
- dirURI := span.URIFromPath(filepath.Dir(pgf.URI.Filename()))
- s.gcOptimizationDetailsMu.Lock()
- _, ok := s.gcOptimizationDetails[dirURI]
- s.gcOptimizationDetailsMu.Unlock()
- if ok {
- gcDetailsDir = dirURI
- }
- }
+ includeAnalysis = includeAnalysis || snapshot.IsOpen(pgf.URI)
}
typeCheckDiagnostics := source.GetTypeCheckDiagnostics(ctx, snapshot, pkg)
@@ -276,10 +264,14 @@
s.storeDiagnostics(snapshot, uri, analysisSource, diags)
}
}
- // If gc optimization details are available, add them to the
+
+ // If gc optimization details are requested, add them to the
// diagnostic reports.
- if gcDetailsDir != "" {
- gcReports, err := source.GCOptimizationDetails(ctx, snapshot, gcDetailsDir)
+ s.gcOptimizationDetailsMu.Lock()
+ _, enableGCDetails := s.gcOptimizationDetails[pkg.ID()]
+ s.gcOptimizationDetailsMu.Unlock()
+ if enableGCDetails {
+ gcReports, err := source.GCOptimizationDetails(ctx, snapshot, pkg)
if err != nil {
event.Error(ctx, "warning: gc details", err, tag.Snapshot.Of(snapshot.ID()), tag.Package.Of(pkg.ID()))
}
diff --git a/internal/lsp/server.go b/internal/lsp/server.go
index df1da8c..793ee5d 100644
--- a/internal/lsp/server.go
+++ b/internal/lsp/server.go
@@ -24,7 +24,7 @@
func NewServer(session source.Session, client protocol.Client) *Server {
return &Server{
diagnostics: map[span.URI]*fileReports{},
- gcOptimizationDetails: make(map[span.URI]struct{}),
+ gcOptimizationDetails: make(map[string]struct{}),
watchedGlobPatterns: make(map[string]struct{}),
changedFiles: make(map[span.URI]struct{}),
session: session,
@@ -91,9 +91,9 @@
// gcOptimizationDetails describes the packages for which we want
// optimization details to be included in the diagnostics. The key is the
- // directory of the package.
+ // ID of the package.
gcOptimizationDetailsMu sync.Mutex
- gcOptimizationDetails map[span.URI]struct{}
+ gcOptimizationDetails map[string]struct{}
// diagnosticsSema limits the concurrency of diagnostics runs, which can be
// expensive.
diff --git a/internal/lsp/source/gc_annotations.go b/internal/lsp/source/gc_annotations.go
index f2a0e67..3616bbf 100644
--- a/internal/lsp/source/gc_annotations.go
+++ b/internal/lsp/source/gc_annotations.go
@@ -35,7 +35,11 @@
Bounds Annotation = "bounds"
)
-func GCOptimizationDetails(ctx context.Context, snapshot Snapshot, pkgDir span.URI) (map[VersionedFileIdentity][]*Diagnostic, error) {
+func GCOptimizationDetails(ctx context.Context, snapshot Snapshot, pkg Package) (map[VersionedFileIdentity][]*Diagnostic, error) {
+ if len(pkg.CompiledGoFiles()) == 0 {
+ return nil, nil
+ }
+ pkgDir := filepath.Dir(pkg.CompiledGoFiles()[0].URI.Filename())
outDir := filepath.Join(os.TempDir(), fmt.Sprintf("gopls-%d.details", os.Getpid()))
if err := os.MkdirAll(outDir, 0700); err != nil {
@@ -60,7 +64,7 @@
fmt.Sprintf("-o=%s", tmpFile.Name()),
".",
},
- WorkingDir: pkgDir.Filename(),
+ WorkingDir: pkgDir,
}
_, err = snapshot.RunGoCommandDirect(ctx, Normal, inv)
if err != nil {
@@ -83,7 +87,7 @@
if fh == nil {
continue
}
- if pkgDir.Filename() != filepath.Dir(fh.URI().Filename()) {
+ if pkgDir != filepath.Dir(fh.URI().Filename()) {
// https://github.com/golang/go/issues/42198
// sometimes the detail diagnostics generated for files
// outside the package can never be taken back.