Skip to content

Commit 2c5d16c

Browse files
mateusz834gopherbot
authored andcommitted
go/ast/astutil: simplify and modernize DeleteNamedImport
Change-Id: I6a6a6964d45b6fe00d3471f62f6d2497c40a6ac7 Reviewed-on: https://go-review.googlesource.com/c/tools/+/703616 Reviewed-by: Alan Donovan <[email protected]> Auto-Submit: Alan Donovan <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Michael Knyszek <[email protected]>
1 parent 9fccddc commit 2c5d16c

File tree

1 file changed

+24
-43
lines changed

1 file changed

+24
-43
lines changed

go/ast/astutil/imports.go

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -209,48 +209,46 @@ func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool)
209209
// DeleteNamedImport deletes the import with the given name and path from the file f, if present.
210210
// If there are duplicate import declarations, all matching ones are deleted.
211211
func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool) {
212-
var delspecs []*ast.ImportSpec
213-
var delcomments []*ast.CommentGroup
212+
var (
213+
delspecs = make(map[*ast.ImportSpec]bool)
214+
delcomments = make(map[*ast.CommentGroup]bool)
215+
)
214216

215217
// Find the import nodes that import path, if any.
216218
for i := 0; i < len(f.Decls); i++ {
217-
decl := f.Decls[i]
218-
gen, ok := decl.(*ast.GenDecl)
219+
gen, ok := f.Decls[i].(*ast.GenDecl)
219220
if !ok || gen.Tok != token.IMPORT {
220221
continue
221222
}
222223
for j := 0; j < len(gen.Specs); j++ {
223-
spec := gen.Specs[j]
224-
impspec := spec.(*ast.ImportSpec)
224+
impspec := gen.Specs[j].(*ast.ImportSpec)
225225
if importName(impspec) != name || importPath(impspec) != path {
226226
continue
227227
}
228228

229229
// We found an import spec that imports path.
230230
// Delete it.
231-
delspecs = append(delspecs, impspec)
231+
delspecs[impspec] = true
232232
deleted = true
233-
copy(gen.Specs[j:], gen.Specs[j+1:])
234-
gen.Specs = gen.Specs[:len(gen.Specs)-1]
233+
gen.Specs = slices.Delete(gen.Specs, j, j+1)
235234

236235
// If this was the last import spec in this decl,
237236
// delete the decl, too.
238237
if len(gen.Specs) == 0 {
239-
copy(f.Decls[i:], f.Decls[i+1:])
240-
f.Decls = f.Decls[:len(f.Decls)-1]
238+
f.Decls = slices.Delete(f.Decls, i, i+1)
241239
i--
242240
break
243241
} else if len(gen.Specs) == 1 {
244242
if impspec.Doc != nil {
245-
delcomments = append(delcomments, impspec.Doc)
243+
delcomments[impspec.Doc] = true
246244
}
247245
if impspec.Comment != nil {
248-
delcomments = append(delcomments, impspec.Comment)
246+
delcomments[impspec.Comment] = true
249247
}
250248
for _, cg := range f.Comments {
251249
// Found comment on the same line as the import spec.
252250
if cg.End() < impspec.Pos() && fset.Position(cg.End()).Line == fset.Position(impspec.Pos()).Line {
253-
delcomments = append(delcomments, cg)
251+
delcomments[cg] = true
254252
break
255253
}
256254
}
@@ -294,38 +292,21 @@ func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (del
294292
}
295293

296294
// Delete imports from f.Imports.
297-
for i := 0; i < len(f.Imports); i++ {
298-
imp := f.Imports[i]
299-
for j, del := range delspecs {
300-
if imp == del {
301-
copy(f.Imports[i:], f.Imports[i+1:])
302-
f.Imports = f.Imports[:len(f.Imports)-1]
303-
copy(delspecs[j:], delspecs[j+1:])
304-
delspecs = delspecs[:len(delspecs)-1]
305-
i--
306-
break
307-
}
308-
}
295+
before := len(f.Imports)
296+
f.Imports = slices.DeleteFunc(f.Imports, func(imp *ast.ImportSpec) bool {
297+
_, ok := delspecs[imp]
298+
return ok
299+
})
300+
if len(f.Imports)+len(delspecs) != before {
301+
// This can happen when the AST is invalid (i.e. imports differ between f.Decls and f.Imports).
302+
panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs))
309303
}
310304

311305
// Delete comments from f.Comments.
312-
for i := 0; i < len(f.Comments); i++ {
313-
cg := f.Comments[i]
314-
for j, del := range delcomments {
315-
if cg == del {
316-
copy(f.Comments[i:], f.Comments[i+1:])
317-
f.Comments = f.Comments[:len(f.Comments)-1]
318-
copy(delcomments[j:], delcomments[j+1:])
319-
delcomments = delcomments[:len(delcomments)-1]
320-
i--
321-
break
322-
}
323-
}
324-
}
325-
326-
if len(delspecs) > 0 {
327-
panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs))
328-
}
306+
f.Comments = slices.DeleteFunc(f.Comments, func(cg *ast.CommentGroup) bool {
307+
_, ok := delcomments[cg]
308+
return ok
309+
})
329310

330311
return
331312
}

0 commit comments

Comments
 (0)