@@ -23,7 +23,6 @@ import (
23
23
"sort"
24
24
"strings"
25
25
"sync"
26
- "time"
27
26
28
27
"golang.org/x/sync/errgroup"
29
28
"golang.org/x/tools/go/analysis"
@@ -32,6 +31,7 @@ import (
32
31
"golang.org/x/tools/gopls/internal/lsp/protocol"
33
32
"golang.org/x/tools/gopls/internal/lsp/source"
34
33
"golang.org/x/tools/internal/event"
34
+ "golang.org/x/tools/internal/event/tag"
35
35
"golang.org/x/tools/internal/facts"
36
36
"golang.org/x/tools/internal/gcimporter"
37
37
"golang.org/x/tools/internal/memoize"
@@ -164,8 +164,6 @@ import (
164
164
// Destroy()
165
165
// - share cache.{goVersionRx,parseGoImpl}
166
166
167
- var born = time .Now ()
168
-
169
167
// Analyze applies a set of analyzers to the package denoted by id,
170
168
// and returns their diagnostics for that package.
171
169
//
@@ -174,9 +172,8 @@ var born = time.Now()
174
172
// Precondition: all analyzers within the process have distinct names.
175
173
// (The names are relied on by the serialization logic.)
176
174
func (s * snapshot ) Analyze (ctx context.Context , id PackageID , analyzers []* source.Analyzer ) ([]* source.Diagnostic , error ) {
177
- if false { // debugging
178
- log .Println ("Analyze@" , time .Since (born )) // called after the 7s IWL in k8s
179
- }
175
+ ctx , done := event .Start (ctx , "snapshot.Analyze" , tag .Package .Of (string (id )))
176
+ defer done ()
180
177
181
178
// Filter and sort enabled root analyzers.
182
179
// A disabled analyzer may still be run if required by another.
@@ -199,19 +196,13 @@ func (s *snapshot) Analyze(ctx context.Context, id PackageID, analyzers []*sourc
199
196
}
200
197
}
201
198
202
- if false { // debugging
203
- // TODO(adonovan): use proper tracing.
204
- t0 := time .Now ()
205
- defer func () {
206
- log .Printf ("%v for analyze(%s, %s)" , time .Since (t0 ), id , enabled )
207
- }()
208
- }
209
-
210
199
// Run the analysis.
211
200
res , err := s .analyze (ctx , id , enabled )
212
201
if err != nil {
213
202
return nil , err
214
203
}
204
+ // Inv: res is the successful result of analyzeImpl(analyzers, id),
205
+ // which augments the successful result of actuallyAnalyze.
215
206
216
207
// Report diagnostics only from enabled actions that succeeded.
217
208
// Errors from creating or analyzing packages are ignored.
@@ -225,7 +216,11 @@ func (s *snapshot) Analyze(ctx context.Context, id PackageID, analyzers []*sourc
225
216
// results, we should propagate the per-action errors.
226
217
var results []* source.Diagnostic
227
218
for _ , a := range enabled {
228
- summary := res .Actions [a .Name ]
219
+ summary , ok := res .Actions [a .Name ]
220
+ if summary == nil {
221
+ panic (fmt .Sprintf ("analyzeSummary.Actions[%q] = (nil, %t); got %v (#60551)" ,
222
+ a .Name , ok , res .Actions ))
223
+ }
229
224
if summary .Err != "" {
230
225
continue // action failed
231
226
}
@@ -309,7 +304,7 @@ type actionSummary struct {
309
304
310
305
// analyze is a memoization of analyzeImpl.
311
306
func (s * snapshot ) analyze (ctx context.Context , id PackageID , analyzers []* analysis.Analyzer ) (* analyzeSummary , error ) {
312
- // Use the sorted list of names of analyzers in the key.
307
+ // Use the caller- sorted list of names of analyzers in the key.
313
308
//
314
309
// TODO(adonovan): opt: account for analysis results at a
315
310
// finer grain to avoid duplicate work when a
@@ -568,6 +563,9 @@ func analysisCacheKey(analyzers []*analysis.Analyzer, m *source.Metadata, compil
568
563
569
564
// actuallyAnalyze implements the cache-miss case.
570
565
// This function does not access the snapshot.
566
+ //
567
+ // Postcondition: on success, the analyzeSummary.Actions
568
+ // key set is {a.Name for a in analyzers}.
571
569
func actuallyAnalyze (ctx context.Context , analyzers []* analysis.Analyzer , m * source.Metadata , vdeps map [PackageID ]* analyzeSummary , compiledGoFiles []source.FileHandle ) (* analyzeSummary , error ) {
572
570
// Create a local FileSet for processing this package only.
573
571
fset := token .NewFileSet ()
@@ -637,6 +635,7 @@ func actuallyAnalyze(ctx context.Context, analyzers []*analysis.Analyzer, m *sou
637
635
638
636
// Execute the graph in parallel.
639
637
execActions (roots )
638
+ // Inv: each root's summary is set (whether success or error).
640
639
641
640
// Don't return (or cache) the result in case of cancellation.
642
641
if err := ctx .Err (); err != nil {
@@ -645,8 +644,11 @@ func actuallyAnalyze(ctx context.Context, analyzers []*analysis.Analyzer, m *sou
645
644
646
645
// Return summaries only for the requested actions.
647
646
summaries := make (map [string ]* actionSummary )
648
- for _ , act := range roots {
649
- summaries [act .a .Name ] = act .summary
647
+ for _ , root := range roots {
648
+ if root .summary == nil {
649
+ panic ("root has nil action.summary (#60551)" )
650
+ }
651
+ summaries [root .a .Name ] = root .summary
650
652
}
651
653
652
654
return & analyzeSummary {
@@ -897,6 +899,7 @@ func (act *action) String() string {
897
899
}
898
900
899
901
// execActions executes a set of action graph nodes in parallel.
902
+ // Postcondition: each action.summary is set, even in case of error.
900
903
func execActions (actions []* action ) {
901
904
var wg sync.WaitGroup
902
905
for _ , act := range actions {
@@ -917,6 +920,9 @@ func execActions(actions []*action) {
917
920
}
918
921
}
919
922
})
923
+ if act .summary == nil {
924
+ panic ("nil action.summary (#60551)" )
925
+ }
920
926
}()
921
927
}
922
928
wg .Wait ()
0 commit comments