diff --git a/README.md b/README.md
index 546706a..36fb2cf 100644
--- a/README.md
+++ b/README.md
@@ -229,6 +229,24 @@ import (
+**Redundant package aliases are removed**
+
+Example
+
+```go
+import (
+ math "math"
+)
+```
+
+```go
+import (
+ "math"
+)
+```
+
+
+
**Short case clauses should take a single line**
Example
diff --git a/format/format.go b/format/format.go
index 7316eb7..71076c3 100644
--- a/format/format.go
+++ b/format/format.go
@@ -24,6 +24,7 @@ import (
"github.com/google/go-cmp/cmp"
"golang.org/x/mod/semver"
"golang.org/x/tools/go/ast/astutil"
+ "golang.org/x/tools/go/packages"
"mvdan.cc/gofumpt/internal/govendor/go/format"
"mvdan.cc/gofumpt/internal/version"
@@ -479,7 +480,7 @@ func (f *fumpter) applyPre(c *astutil.Cursor) {
case *ast.GenDecl:
if node.Tok == token.IMPORT && node.Lparen.IsValid() {
- f.joinStdImports(node)
+ f.tidyImports(node)
}
// Single var declarations shouldn't use parentheses, unless
@@ -930,9 +931,10 @@ func isCgoImport(decl *ast.GenDecl) bool {
return v == "C"
}
-// joinStdImports ensures that all standard library imports are together and at
-// the top of the imports list.
-func (f *fumpter) joinStdImports(d *ast.GenDecl) {
+// tidyImports ensures that:
+// - all standard library imports are together and at the top of the imports list, and
+// - any redundant package aliases are removed.
+func (f *fumpter) tidyImports(d *ast.GenDecl) {
var std, other []ast.Spec
firstGroup := true
lastEnd := d.Pos()
@@ -956,6 +958,23 @@ func (f *fumpter) joinStdImports(d *ast.GenDecl) {
for i, spec := range d.Specs {
spec := spec.(*ast.ImportSpec)
+ path, err := strconv.Unquote(spec.Path.Value)
+ if err != nil {
+ panic(err) // should never error
+ }
+
+ // If we import a package with an alias (i.e., if spec.Name is non-nil), and
+ // if the alias is the same as the package's name, then we remove the alias.
+ if spec.Name != nil {
+ packages, err := packages.Load(&packages.Config{Mode: packages.NeedName}, path)
+ if err != nil || len(packages) != 1 {
+ panic(fmt.Sprintf("loading the package %q: %v", path, err)) // should never error
+ }
+ if packages[0].Name == spec.Name.Name {
+ spec.Name = nil
+ }
+ }
+
if coms := f.commentsBetween(lastEnd, spec.Pos()); len(coms) > 0 {
lastEnd = coms[len(coms)-1].End()
}
@@ -966,10 +985,6 @@ func (f *fumpter) joinStdImports(d *ast.GenDecl) {
lastEnd = spec.End()
}
- path, err := strconv.Unquote(spec.Path.Value)
- if err != nil {
- panic(err) // should never error
- }
periodIndex := strings.IndexByte(path, '.')
slashIndex := strings.IndexByte(path, '/')
switch {
diff --git a/testdata/script/std-imports.txtar b/testdata/script/std-imports.txtar
index 4053ae7..b017d93 100644
--- a/testdata/script/std-imports.txtar
+++ b/testdata/script/std-imports.txtar
@@ -48,7 +48,7 @@ import (
import (
"foo.local"
"foo.local/three"
- math "math"
+ maths "math"
)
import (
@@ -99,6 +99,12 @@ import (
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/yaml"
)
+
+// Redundant package aliases are removed.
+import (
+ filepath "path/filepath"
+ "time"
+)
-- foo.go.golden --
package p
@@ -135,7 +141,7 @@ import (
// We need to split std vs non-std in this case too.
import (
- math "math"
+ maths "math"
"foo.local"
"foo.local/three"
@@ -191,3 +197,9 @@ import (
"sigs.k8s.io/yaml"
)
+
+// Redundant package aliases are removed.
+import (
+ "path/filepath"
+ "time"
+)