@@ -209,48 +209,46 @@ func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool)
209
209
// DeleteNamedImport deletes the import with the given name and path from the file f, if present.
210
210
// If there are duplicate import declarations, all matching ones are deleted.
211
211
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
+ )
214
216
215
217
// Find the import nodes that import path, if any.
216
218
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 )
219
220
if ! ok || gen .Tok != token .IMPORT {
220
221
continue
221
222
}
222
223
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 )
225
225
if importName (impspec ) != name || importPath (impspec ) != path {
226
226
continue
227
227
}
228
228
229
229
// We found an import spec that imports path.
230
230
// Delete it.
231
- delspecs = append ( delspecs , impspec )
231
+ delspecs [ impspec ] = true
232
232
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 )
235
234
236
235
// If this was the last import spec in this decl,
237
236
// delete the decl, too.
238
237
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 )
241
239
i --
242
240
break
243
241
} else if len (gen .Specs ) == 1 {
244
242
if impspec .Doc != nil {
245
- delcomments = append ( delcomments , impspec .Doc )
243
+ delcomments [ impspec .Doc ] = true
246
244
}
247
245
if impspec .Comment != nil {
248
- delcomments = append ( delcomments , impspec .Comment )
246
+ delcomments [ impspec .Comment ] = true
249
247
}
250
248
for _ , cg := range f .Comments {
251
249
// Found comment on the same line as the import spec.
252
250
if cg .End () < impspec .Pos () && fset .Position (cg .End ()).Line == fset .Position (impspec .Pos ()).Line {
253
- delcomments = append ( delcomments , cg )
251
+ delcomments [ cg ] = true
254
252
break
255
253
}
256
254
}
@@ -294,38 +292,21 @@ func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (del
294
292
}
295
293
296
294
// 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 ))
309
303
}
310
304
311
305
// 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
+ })
329
310
330
311
return
331
312
}
0 commit comments