for j, s := range d.Specs {
if j > i && lineAt(fset, s.Pos()) > 1+lineAt(fset, d.Specs[j-1].End()) {
// j begins a new run. End this one.
- specs = append(specs, sortSpecs(fset, f, d.Specs[i:j])...)
+ specs = append(specs, sortSpecs(fset, f, d, d.Specs[i:j])...)
i = j
}
}
- specs = append(specs, sortSpecs(fset, f, d.Specs[i:])...)
+ specs = append(specs, sortSpecs(fset, f, d, d.Specs[i:])...)
d.Specs = specs
// Deduping can leave a blank line before the rparen; clean that up.
cg *CommentGroup
}
-func sortSpecs(fset *token.FileSet, f *File, specs []Spec) []Spec {
+func sortSpecs(fset *token.FileSet, f *File, d *GenDecl, specs []Spec) []Spec {
// Can't short-circuit here even if specs are already sorted,
// since they might yet need deduplication.
// A lone import, however, may be safely ignored.
deduped = append(deduped, s)
} else {
p := s.Pos()
- fset.File(p).MergeLine(lineAt(fset, p))
+ // This function is exited early when len(specs) <= 1,
+ // so d.Rparen must be populated (d.Rparen.IsValid() == true).
+ if l := lineAt(fset, p); l != lineAt(fset, d.Rparen) {
+ fset.File(p).MergeLine(l)
+ }
}
}
specs = deduped
}
})
}
+
+func TestIssue69183(t *testing.T) {
+ const src = `package A
+import (
+"a"//a
+"a")
+`
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, "test.go", src, parser.ParseComments|parser.SkipObjectResolution)
+ if err != nil {
+ t.Fatal(err)
+ }
+ ast.SortImports(fset, f) // should not panic
+}
+
+func TestSortImportsSameLastLine(t *testing.T) {
+ const src = `package A
+import (
+"a"//a
+"a")
+func a() {}
+`
+
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, "test.go", src, parser.ParseComments|parser.SkipObjectResolution)
+ if err != nil {
+ t.Fatal(err)
+ }
+ ast.SortImports(fset, f)
+ fd := f.Decls[1].(*ast.FuncDecl)
+ fdPos := fset.Position(fd.Pos())
+ // After SortImports, the Position of the func, should still be at Column == 1.
+ // This is related to the issue: https://go.dev/issue/69183, we were merging lines
+ // incorrectly, which caused the position to be Column = 6, Line = 4.
+ if fdPos.Column != 1 {
+ t.Errorf("invalid fdPos.Column = %v; want = 1", fdPos.Column)
+ }
+ if fdPos.Line != 5 {
+ t.Errorf("invalid fdPos.Line = %v; want = 5", fdPos.Line)
+ }
+}