Skip to content

Commit 4ac71c0

Browse files
committed
internal/imports: sort fixes for deterministic results
Fixes golang/go#59976 Change-Id: I59c309e126b1ec4cd05c50e5af8e5df8cfe49072 Reviewed-on: https://go-review.googlesource.com/c/tools/+/492738 gopls-CI: kokoro <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Alan Donovan <[email protected]> Run-TryBot: Robert Findley <[email protected]>
1 parent 573915d commit 4ac71c0

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

gopls/internal/regtest/marker/testdata/codeaction/imports.txt

+9-3
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,7 @@ func _() {
151151
}
152152

153153
-- removeall.go --
154-
// TODO(golang/go#59976): this test is flaky because it leaves one comment
155-
// behind, but non-deterministically.
156-
package imports // codeaction("source.organizeImports", "package", "", removeall)
154+
package imports //@codeaction("source.organizeImports", "package", "", removeall)
157155

158156
import (
159157
"bytes" //@diag("\"bytes\"", re"not used")
@@ -164,6 +162,14 @@ import (
164162
func _() {
165163
}
166164

165+
-- @removeall/removeall.go --
166+
package imports //@codeaction("source.organizeImports", "package", "", removeall)
167+
168+
//@diag("\"fmt\"", re"not used")
169+
170+
func _() {
171+
}
172+
167173
-- twolines.go --
168174
package imports
169175
func main() {} //@codeactionerr("source.organizeImports", "main", "", re"found 0")

internal/imports/fix.go

+27-3
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,16 @@ func (p *pass) fix() ([]*ImportFix, bool) {
414414
})
415415
}
416416
}
417-
417+
// Collecting fixes involved map iteration, so sort for stability. See
418+
// golang/go#59976.
419+
sortFixes(fixes)
420+
421+
// collect selected fixes in a separate slice, so that it can be sorted
422+
// separately. Note that these fixes must occur after fixes to existing
423+
// imports. TODO(rfindley): figure out why.
424+
var selectedFixes []*ImportFix
418425
for _, imp := range selected {
419-
fixes = append(fixes, &ImportFix{
426+
selectedFixes = append(selectedFixes, &ImportFix{
420427
StmtInfo: ImportInfo{
421428
Name: p.importSpecName(imp),
422429
ImportPath: imp.ImportPath,
@@ -425,8 +432,25 @@ func (p *pass) fix() ([]*ImportFix, bool) {
425432
FixType: AddImport,
426433
})
427434
}
435+
sortFixes(selectedFixes)
436+
437+
return append(fixes, selectedFixes...), true
438+
}
428439

429-
return fixes, true
440+
func sortFixes(fixes []*ImportFix) {
441+
sort.Slice(fixes, func(i, j int) bool {
442+
fi, fj := fixes[i], fixes[j]
443+
if fi.StmtInfo.ImportPath != fj.StmtInfo.ImportPath {
444+
return fi.StmtInfo.ImportPath < fj.StmtInfo.ImportPath
445+
}
446+
if fi.StmtInfo.Name != fj.StmtInfo.Name {
447+
return fi.StmtInfo.Name < fj.StmtInfo.Name
448+
}
449+
if fi.IdentName != fj.IdentName {
450+
return fi.IdentName < fj.IdentName
451+
}
452+
return fi.FixType < fj.FixType
453+
})
430454
}
431455

432456
// importSpecName gets the import name of imp in the import spec.

0 commit comments

Comments
 (0)