diff -r 131f8c8eb722 src/cmd/gofmt/testdata/import.golden --- a/src/cmd/gofmt/testdata/import.golden Wed Mar 06 16:52:03 2013 -0800 +++ b/src/cmd/gofmt/testdata/import.golden Thu Mar 07 14:55:48 2013 +0100 @@ -106,3 +106,13 @@ "log" // for Fatal "math" ) + +import ( + err1 "errors" + err2 "errors" + "fmt" + "io" + "os" // os1 + "os" // os2 + +) diff -r 131f8c8eb722 src/cmd/gofmt/testdata/import.input --- a/src/cmd/gofmt/testdata/import.input Wed Mar 06 16:52:03 2013 -0800 +++ b/src/cmd/gofmt/testdata/import.input Thu Mar 07 14:55:48 2013 +0100 @@ -106,3 +106,14 @@ "errors" "io" // for Reader ) + +import ( + "io" + "fmt" + "fmt" + "os" // os1 + "os" // os2 + err1 "errors" + err2 "errors" + "fmt" +) diff -r 131f8c8eb722 src/pkg/go/ast/import.go --- a/src/pkg/go/ast/import.go Wed Mar 06 16:52:03 2013 -0800 +++ b/src/pkg/go/ast/import.go Thu Mar 07 14:55:48 2013 +0100 @@ -5,6 +5,7 @@ package ast import ( + "fmt" "go/token" "sort" "strconv" @@ -26,18 +27,55 @@ } // Identify and sort runs of specs on successive lines. + var specs []Spec i := 0 for j, s := range d.Specs { if j > i && fset.Position(s.Pos()).Line > 1+fset.Position(d.Specs[j-1].End()).Line { // j begins a new run. End this one. - sortSpecs(fset, f, d.Specs[i:j]) + run := d.Specs[i:j] + run = removeDuplicateImports(run) + sortSpecs(fset, f, run) + specs = append(specs, run...) i = j } } - sortSpecs(fset, f, d.Specs[i:]) + run := d.Specs[i:] + run = removeDuplicateImports(run) + sortSpecs(fset, f, run) + specs = append(specs, run...) + d.Specs = specs } } +// Returns the unique ID of the ImportSpec +func importSpecID(s *ImportSpec) string { + return fmt.Sprintf("(%v)(%v)", s.Name, s.Path.Value) +} + +func removeDuplicateImports(specs []Spec) []Spec { + var filtered []Spec + ids := make(map[string]bool) + + for _, spec := range specs { + imp := spec.(*ImportSpec) + + var id = "" + if imp.Doc == nil && imp.Comment == nil { + id = importSpecID(imp) + if ids[id] { + continue + } + } + + filtered = append(filtered, imp) + if id != "" { + ids[id] = true + } + } + + return filtered +} + func importPath(s Spec) string { t, err := strconv.Unquote(s.(*ImportSpec).Path.Value) if err == nil {