Skip to content

Commit f1a3b12

Browse files
findleyrgopherbot
authored andcommitted
internal/imports: FixImports should be cancellable
Historically, FixImports did not have access to a context, and performed its imports scan with context.Background. Since then, FixImports is called by gopls with the CodeAction Context, yet cancelling this context does not abort the scan. Fix this by using the correct context, and checking context cancellation before parsing. It's a little hard to see that context cancellation doesn't leave the process environent in a broken state, but we can infer that this is OK because other scans (such as that used by unimported completion) do cancel their context. Additionally, remove a 'fixImportsDefault' extensibility seam that is apparently unused after six years. For golang/go#67289 Change-Id: I32261b1bfb38af32880e981cd2423414069b32a3 Reviewed-on: https://go-review.googlesource.com/c/tools/+/589975 LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Robert Findley <[email protected]> Reviewed-by: Alan Donovan <[email protected]>
1 parent 4478db0 commit f1a3b12

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

internal/imports/fix.go

+16-12
Original file line numberDiff line numberDiff line change
@@ -104,19 +104,25 @@ type packageInfo struct {
104104

105105
// parseOtherFiles parses all the Go files in srcDir except filename, including
106106
// test files if filename looks like a test.
107-
func parseOtherFiles(fset *token.FileSet, srcDir, filename string) []*ast.File {
107+
//
108+
// It returns an error only if ctx is cancelled. Files with parse errors are
109+
// ignored.
110+
func parseOtherFiles(ctx context.Context, fset *token.FileSet, srcDir, filename string) ([]*ast.File, error) {
108111
// This could use go/packages but it doesn't buy much, and it fails
109112
// with https://golang.org/issue/26296 in LoadFiles mode in some cases.
110113
considerTests := strings.HasSuffix(filename, "_test.go")
111114

112115
fileBase := filepath.Base(filename)
113116
packageFileInfos, err := os.ReadDir(srcDir)
114117
if err != nil {
115-
return nil
118+
return nil, ctx.Err()
116119
}
117120

118121
var files []*ast.File
119122
for _, fi := range packageFileInfos {
123+
if ctx.Err() != nil {
124+
return nil, ctx.Err()
125+
}
120126
if fi.Name() == fileBase || !strings.HasSuffix(fi.Name(), ".go") {
121127
continue
122128
}
@@ -132,7 +138,7 @@ func parseOtherFiles(fset *token.FileSet, srcDir, filename string) []*ast.File {
132138
files = append(files, f)
133139
}
134140

135-
return files
141+
return files, ctx.Err()
136142
}
137143

138144
// addGlobals puts the names of package vars into the provided map.
@@ -557,12 +563,7 @@ func (p *pass) addCandidate(imp *ImportInfo, pkg *packageInfo) {
557563

558564
// fixImports adds and removes imports from f so that all its references are
559565
// satisfied and there are no unused imports.
560-
//
561-
// This is declared as a variable rather than a function so goimports can
562-
// easily be extended by adding a file with an init function.
563-
var fixImports = fixImportsDefault
564-
565-
func fixImportsDefault(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv) error {
566+
func fixImports(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv) error {
566567
fixes, err := getFixes(context.Background(), fset, f, filename, env)
567568
if err != nil {
568569
return err
@@ -592,7 +593,10 @@ func getFixes(ctx context.Context, fset *token.FileSet, f *ast.File, filename st
592593
return fixes, nil
593594
}
594595

595-
otherFiles := parseOtherFiles(fset, srcDir, filename)
596+
otherFiles, err := parseOtherFiles(ctx, fset, srcDir, filename)
597+
if err != nil {
598+
return nil, err
599+
}
596600

597601
// Second pass: add information from other files in the same package,
598602
// like their package vars and imports.
@@ -1192,7 +1196,7 @@ func addExternalCandidates(ctx context.Context, pass *pass, refs references, fil
11921196
if err != nil {
11931197
return err
11941198
}
1195-
if err = resolver.scan(context.Background(), callback); err != nil {
1199+
if err = resolver.scan(ctx, callback); err != nil {
11961200
return err
11971201
}
11981202

@@ -1203,7 +1207,7 @@ func addExternalCandidates(ctx context.Context, pass *pass, refs references, fil
12031207
}
12041208
results := make(chan result, len(refs))
12051209

1206-
ctx, cancel := context.WithCancel(context.TODO())
1210+
ctx, cancel := context.WithCancel(ctx)
12071211
var wg sync.WaitGroup
12081212
defer func() {
12091213
cancel()

0 commit comments

Comments
 (0)