Skip to content

Commit c6b416e

Browse files
committed
internal/lsp: add more error handling to analysis
Updates golang/go#30786 Change-Id: Icf054b9bcd62b36e3aa55288946a9f0d1c845300 Reviewed-on: https://go-review.googlesource.com/c/tools/+/172972 Run-TryBot: Rebecca Stambler <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Cottrell <[email protected]>
1 parent 3ff669b commit c6b416e

File tree

2 files changed

+34
-26
lines changed

2 files changed

+34
-26
lines changed

internal/lsp/source/analysis.go

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,32 @@ import (
1818
"sync"
1919
"time"
2020

21+
"golang.org/x/sync/errgroup"
2122
"golang.org/x/tools/go/analysis"
2223
)
2324

24-
func analyze(ctx context.Context, v View, pkgs []Package, analyzers []*analysis.Analyzer) []*Action {
25+
func analyze(ctx context.Context, v View, pkgs []Package, analyzers []*analysis.Analyzer) ([]*Action, error) {
26+
if ctx.Err() != nil {
27+
return nil, ctx.Err()
28+
}
29+
2530
// Build nodes for initial packages.
2631
var roots []*Action
2732
for _, a := range analyzers {
2833
for _, pkg := range pkgs {
2934
root, err := pkg.GetActionGraph(ctx, a)
3035
if err != nil {
31-
continue
36+
return nil, err
3237
}
3338
root.isroot = true
3439
roots = append(roots, root)
3540
}
3641
}
3742

3843
// Execute the graph in parallel.
39-
execAll(v.FileSet(), roots)
44+
execAll(ctx, v.FileSet(), roots)
4045

41-
return roots
46+
return roots, nil
4247
}
4348

4449
// An action represents one unit of analysis work: the application of
@@ -75,28 +80,27 @@ func (act *Action) String() string {
7580
return fmt.Sprintf("%s@%s", act.Analyzer, act.Pkg)
7681
}
7782

78-
func execAll(fset *token.FileSet, actions []*Action) {
79-
var wg sync.WaitGroup
83+
func execAll(ctx context.Context, fset *token.FileSet, actions []*Action) error {
84+
g, ctx := errgroup.WithContext(ctx)
8085
for _, act := range actions {
81-
wg.Add(1)
82-
work := func(act *Action) {
83-
act.exec(fset)
84-
wg.Done()
85-
}
86-
go work(act)
86+
act := act
87+
g.Go(func() error {
88+
act.exec(ctx, fset)
89+
return nil
90+
})
8791
}
88-
wg.Wait()
92+
return g.Wait()
8993
}
9094

91-
func (act *Action) exec(fset *token.FileSet) {
95+
func (act *Action) exec(ctx context.Context, fset *token.FileSet) {
9296
act.once.Do(func() {
93-
act.execOnce(fset)
97+
act.execOnce(ctx, fset)
9498
})
9599
}
96100

97-
func (act *Action) execOnce(fset *token.FileSet) {
101+
func (act *Action) execOnce(ctx context.Context, fset *token.FileSet) {
98102
// Analyze dependencies.
99-
execAll(fset, act.Deps)
103+
execAll(ctx, fset, act.Deps)
100104

101105
// Report an error if any dependency failed.
102106
var failed []string

internal/lsp/source/diagnostics.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,12 @@ func Diagnostics(ctx context.Context, v View, uri span.URI) (map[span.URI][]Diag
101101
return reports, nil
102102
}
103103
// Type checking and parsing succeeded. Run analyses.
104-
runAnalyses(ctx, v, pkg, func(a *analysis.Analyzer, diag analysis.Diagnostic) {
104+
runAnalyses(ctx, v, pkg, func(a *analysis.Analyzer, diag analysis.Diagnostic) error {
105105
r := span.NewRange(v.FileSet(), diag.Pos, 0)
106106
s, err := r.Span()
107107
if err != nil {
108-
//TODO: we could not process the diag.Pos, and thus have no valid span
109-
//we don't have anywhere to put this error though
110-
v.Logger().Errorf(ctx, "%v", err)
108+
// The diagnostic has an invalid position, so we don't have a valid span.
109+
return err
111110
}
112111
category := a.Name
113112
if diag.Category != "" {
@@ -119,6 +118,7 @@ func Diagnostics(ctx context.Context, v View, uri span.URI) (map[span.URI][]Diag
119118
Message: diag.Message,
120119
Severity: SeverityWarning,
121120
})
121+
return nil
122122
})
123123

124124
return reports, nil
@@ -168,8 +168,8 @@ func singleDiagnostic(uri span.URI, format string, a ...interface{}) map[span.UR
168168
}
169169
}
170170

171-
func runAnalyses(ctx context.Context, v View, pkg Package, report func(a *analysis.Analyzer, diag analysis.Diagnostic)) error {
172-
// the traditional vet suite:
171+
func runAnalyses(ctx context.Context, v View, pkg Package, report func(a *analysis.Analyzer, diag analysis.Diagnostic) error) error {
172+
// The traditional vet suite:
173173
analyzers := []*analysis.Analyzer{
174174
asmdecl.Analyzer,
175175
assign.Analyzer,
@@ -195,7 +195,10 @@ func runAnalyses(ctx context.Context, v View, pkg Package, report func(a *analys
195195
unusedresult.Analyzer,
196196
}
197197

198-
roots := analyze(ctx, v, []Package{pkg}, analyzers)
198+
roots, err := analyze(ctx, v, []Package{pkg}, analyzers)
199+
if err != nil {
200+
return err
201+
}
199202

200203
// Report diagnostics and errors from root analyzers.
201204
for _, r := range roots {
@@ -205,9 +208,10 @@ func runAnalyses(ctx context.Context, v View, pkg Package, report func(a *analys
205208
// which isn't super useful...
206209
return r.err
207210
}
208-
report(r.Analyzer, diag)
211+
if err := report(r.Analyzer, diag); err != nil {
212+
return err
213+
}
209214
}
210215
}
211-
212216
return nil
213217
}

0 commit comments

Comments
 (0)