1
0
mirror of https://github.com/golang/go synced 2024-11-18 16:14:46 -07:00

go.tools/astutil: delete all matching imports in DeleteImport

Fixes golang/go#8459.

LGTM=crawshaw, bradfitz
R=bradfitz, crawshaw
CC=golang-codereviews
https://golang.org/cl/128220043
This commit is contained in:
Josh Bleecher Snyder 2014-08-14 11:51:51 -07:00
parent f13ba78920
commit cc1e254c18
3 changed files with 107 additions and 17 deletions

View File

@ -131,22 +131,25 @@ func AddNamedImport(fset *token.FileSet, f *ast.File, name, ipath string) (added
// DeleteImport deletes the import path from the file f, if present. // DeleteImport deletes the import path from the file f, if present.
func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool) { func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool) {
oldImport := importSpec(f, path) var delspecs []*ast.ImportSpec
// Find the import node that imports path, if any. // Find the import nodes that import path, if any.
for i, decl := range f.Decls { for i := 0; i < len(f.Decls); i++ {
decl := f.Decls[i]
gen, ok := decl.(*ast.GenDecl) gen, ok := decl.(*ast.GenDecl)
if !ok || gen.Tok != token.IMPORT { if !ok || gen.Tok != token.IMPORT {
continue continue
} }
for j, spec := range gen.Specs { for j := 0; j < len(gen.Specs); j++ {
spec := gen.Specs[j]
impspec := spec.(*ast.ImportSpec) impspec := spec.(*ast.ImportSpec)
if oldImport != impspec { if importPath(impspec) != path {
continue continue
} }
// We found an import spec that imports path. // We found an import spec that imports path.
// Delete it. // Delete it.
delspecs = append(delspecs, impspec)
deleted = true deleted = true
copy(gen.Specs[j:], gen.Specs[j+1:]) copy(gen.Specs[j:], gen.Specs[j+1:])
gen.Specs = gen.Specs[:len(gen.Specs)-1] gen.Specs = gen.Specs[:len(gen.Specs)-1]
@ -156,6 +159,8 @@ func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool)
if len(gen.Specs) == 0 { if len(gen.Specs) == 0 {
copy(f.Decls[i:], f.Decls[i+1:]) copy(f.Decls[i:], f.Decls[i+1:])
f.Decls = f.Decls[:len(f.Decls)-1] f.Decls = f.Decls[:len(f.Decls)-1]
i--
break
} else if len(gen.Specs) == 1 { } else if len(gen.Specs) == 1 {
gen.Lparen = token.NoPos // drop parens gen.Lparen = token.NoPos // drop parens
} }
@ -167,28 +172,36 @@ func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool)
// We deleted an entry but now there may be // We deleted an entry but now there may be
// a blank line-sized hole where the import was. // a blank line-sized hole where the import was.
if line-lastLine > 1 { if line-lastLine > 1 {
// There was a blank line immediately preceeing the deleted import, // There was a blank line immediately preceding the deleted import,
// so there's no need to close the hole. // so there's no need to close the hole.
// Do nothing. // Do nothing.
} else { } else {
// There was no blank line. // There was no blank line. Close the hole.
// Close the hole by making the previous fset.File(gen.Rparen).MergeLine(line)
// import appear to "end" where this one did.
lastImpspec.EndPos = impspec.End()
} }
} }
break j--
} }
} }
// Delete it from f.Imports. // Delete them from f.Imports.
for i, imp := range f.Imports { for i := 0; i < len(f.Imports); i++ {
if imp == oldImport { imp := f.Imports[i]
for j, del := range delspecs {
if imp == del {
copy(f.Imports[i:], f.Imports[i+1:]) copy(f.Imports[i:], f.Imports[i+1:])
f.Imports = f.Imports[:len(f.Imports)-1] f.Imports = f.Imports[:len(f.Imports)-1]
copy(delspecs[j:], delspecs[j+1:])
delspecs = delspecs[:len(delspecs)-1]
i--
break break
} }
} }
}
if len(delspecs) > 0 {
panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs))
}
return return
} }

View File

@ -463,6 +463,57 @@ import (
"go/format" // e "go/format" // e
) )
`,
},
{
name: "import.15",
pkg: "double",
in: `package main
import (
"double"
"double"
)
`,
out: `package main
`,
},
{
name: "import.16",
pkg: "bubble",
in: `package main
import (
"toil"
"bubble"
"bubble"
"trouble"
)
`,
out: `package main
import (
"toil"
"trouble"
)
`,
},
{
name: "import.17",
pkg: "quad",
in: `package main
import (
"quad"
"quad"
)
import (
"quad"
"quad"
)
`,
out: `package main
`, `,
}, },
} }

View File

@ -643,6 +643,32 @@ import (
) )
func main() { _, _ = fmt.Print, ast.Walk } func main() { _, _ = fmt.Print, ast.Walk }
`,
},
// Failure to delete all duplicate imports
// golang.org/issue/8459
{
name: "issue 8459",
in: `package main
import (
"fmt"
"log"
"log"
"math"
)
func main() { fmt.Println("pi:", math.Pi) }
`,
out: `package main
import (
"fmt"
"math"
)
func main() { fmt.Println("pi:", math.Pi) }
`, `,
}, },
} }