2020package modfile
2121
2222import (
23+ "cmp"
2324 "errors"
2425 "fmt"
2526 "path/filepath"
26- "sort "
27+ "slices "
2728 "strconv"
2829 "strings"
2930 "unicode"
@@ -1633,15 +1634,13 @@ func (f *File) SortBlocks() {
16331634 if ! ok {
16341635 continue
16351636 }
1636- less := lineLess
1637+ less := compareLine
16371638 if block .Token [0 ] == "exclude" && useSemanticSortForExclude {
1638- less = lineExcludeLess
1639+ less = compareLineExclude
16391640 } else if block .Token [0 ] == "retract" {
1640- less = lineRetractLess
1641+ less = compareLineRetract
16411642 }
1642- sort .SliceStable (block .Line , func (i , j int ) bool {
1643- return less (block .Line [i ], block .Line [j ])
1644- })
1643+ slices .SortStableFunc (block .Line , less )
16451644 }
16461645}
16471646
@@ -1746,39 +1745,38 @@ func removeDups(syntax *FileSyntax, exclude *[]*Exclude, replace *[]*Replace, to
17461745 syntax .Stmt = stmts
17471746}
17481747
1749- // lineLess returns whether li should be sorted before lj. It sorts
1750- // lexicographically without assigning any special meaning to tokens.
1751- func lineLess (li , lj * Line ) bool {
1748+ // compareLine compares li and lj. It sorts lexicographically without assigning
1749+ // any special meaning to tokens.
1750+ func compareLine (li , lj * Line ) int {
17521751 for k := 0 ; k < len (li .Token ) && k < len (lj .Token ); k ++ {
17531752 if li .Token [k ] != lj .Token [k ] {
1754- return li .Token [k ] < lj .Token [k ]
1753+ return cmp . Compare ( li .Token [k ], lj .Token [k ])
17551754 }
17561755 }
1757- return len (li .Token ) < len (lj .Token )
1756+ return cmp . Compare ( len (li .Token ), len (lj .Token ) )
17581757}
17591758
1760- // lineExcludeLess reports whether li should be sorted before lj for lines in
1761- // an "exclude" block.
1762- func lineExcludeLess (li , lj * Line ) bool {
1759+ // compareLineExclude compares li and lj for lines in an "exclude" block.
1760+ func compareLineExclude (li , lj * Line ) int {
17631761 if len (li .Token ) != 2 || len (lj .Token ) != 2 {
17641762 // Not a known exclude specification.
17651763 // Fall back to sorting lexicographically.
1766- return lineLess (li , lj )
1764+ return compareLine (li , lj )
17671765 }
17681766 // An exclude specification has two tokens: ModulePath and Version.
17691767 // Compare module path by string order and version by semver rules.
17701768 if pi , pj := li .Token [0 ], lj .Token [0 ]; pi != pj {
1771- return pi < pj
1769+ return cmp . Compare ( pi , pj )
17721770 }
1773- return semver .Compare (li .Token [1 ], lj .Token [1 ]) < 0
1771+ return semver .Compare (li .Token [1 ], lj .Token [1 ])
17741772}
17751773
1776- // lineRetractLess returns whether li should be sorted before lj for lines in
1777- // a "retract" block. It treats each line as a version interval. Single versions
1778- // are compared as if they were intervals with the same low and high version.
1774+ // compareLineRetract compares li and lj for lines in a "retract" block.
1775+ // It treats each line as a version interval. Single versions are compared as
1776+ // if they were intervals with the same low and high version.
17791777// Intervals are sorted in descending order, first by low version, then by
1780- // high version, using semver.Compare.
1781- func lineRetractLess (li , lj * Line ) bool {
1778+ // high version, using [ semver.Compare] .
1779+ func compareLineRetract (li , lj * Line ) int {
17821780 interval := func (l * Line ) VersionInterval {
17831781 if len (l .Token ) == 1 {
17841782 return VersionInterval {Low : l .Token [0 ], High : l .Token [0 ]}
@@ -1792,9 +1790,9 @@ func lineRetractLess(li, lj *Line) bool {
17921790 vii := interval (li )
17931791 vij := interval (lj )
17941792 if cmp := semver .Compare (vii .Low , vij .Low ); cmp != 0 {
1795- return cmp > 0
1793+ return - cmp
17961794 }
1797- return semver .Compare (vii .High , vij .High ) > 0
1795+ return - semver .Compare (vii .High , vij .High )
17981796}
17991797
18001798// checkCanonicalVersion returns a non-nil error if vers is not a canonical
0 commit comments