@@ -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.
211211func 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