Skip to content

Commit

Permalink
Remove redundant package aliases from import blocks
Browse files Browse the repository at this point in the history
I noticed that

```go
package main

import (
	foo "gofumpt-ex/foo"
)

func main() {
	foo.Foo("goodbye, world!")
}
```

wasn't being simplified to

```go
package main

import (
	"gofumpt-ex/foo"
)

func main() {
	foo.Foo("goodbye, world!")
}
```

when the package name of "gofumpt-ex/foo" is "foo". This commit adds
handling for this.
  • Loading branch information
adamroyjones committed Feb 14, 2024
1 parent 636d7a7 commit f7de7e2
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,24 @@ import (

</details>

**Redundant package aliases are removed**

<details><summary><i>Example</i></summary>

```go
import (
math "math"
)
```

```go
import (
"math"
)
```

</details>

**Short case clauses should take a single line**

<details><summary><i>Example</i></summary>
Expand Down
31 changes: 23 additions & 8 deletions format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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()
}
Expand All @@ -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 {
Expand Down
16 changes: 14 additions & 2 deletions testdata/script/std-imports.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import (
import (
"foo.local"
"foo.local/three"
math "math"
maths "math"
)

import (
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -191,3 +197,9 @@ import (

"sigs.k8s.io/yaml"
)

// Redundant package aliases are removed.
import (
"path/filepath"
"time"
)

0 comments on commit f7de7e2

Please sign in to comment.