Skip to content

Commit bf516ba

Browse files
committed
gopls/internal/util/moremaps: use Sorted throughout gopls
This CL (written in passing while thinking about modernizers) replaces each place that allocates a slice of map keys, sorts them, and ranges over the slice, with "for k, v := range moremaps.Sorted(m)". It also adds moremaps.SortedFunc for symmetry. Updates golang/go#68598 Change-Id: I526ddf2398e7cee77f8369fc7a977e6f64727f27 Reviewed-on: https://go-review.googlesource.com/c/tools/+/639135 Auto-Submit: Alan Donovan <[email protected]> Reviewed-by: Robert Findley <[email protected]> Commit-Queue: Alan Donovan <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 4f820db commit bf516ba

File tree

7 files changed

+34
-66
lines changed

7 files changed

+34
-66
lines changed

gopls/internal/cache/analysis.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -490,14 +490,7 @@ func (an *analysisNode) summaryHash() file.Hash {
490490
fmt.Fprintf(hasher, "compiles: %t\n", an.summary.Compiles)
491491

492492
// action results: errors and facts
493-
actions := an.summary.Actions
494-
names := make([]string, 0, len(actions))
495-
for name := range actions {
496-
names = append(names, name)
497-
}
498-
sort.Strings(names)
499-
for _, name := range names {
500-
summary := actions[name]
493+
for name, summary := range moremaps.Sorted(an.summary.Actions) {
501494
fmt.Fprintf(hasher, "action %s\n", name)
502495
if summary.Err != "" {
503496
fmt.Fprintf(hasher, "error %s\n", summary.Err)

gopls/internal/cache/check.go

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"golang.org/x/tools/gopls/internal/label"
3434
"golang.org/x/tools/gopls/internal/protocol"
3535
"golang.org/x/tools/gopls/internal/util/bug"
36+
"golang.org/x/tools/gopls/internal/util/moremaps"
3637
"golang.org/x/tools/gopls/internal/util/safetoken"
3738
"golang.org/x/tools/internal/analysisinternal"
3839
"golang.org/x/tools/internal/event"
@@ -1314,13 +1315,7 @@ func typerefsKey(id PackageID, imports map[ImportPath]*metadata.Package, compile
13141315

13151316
fmt.Fprintf(hasher, "typerefs: %s\n", id)
13161317

1317-
importPaths := make([]string, 0, len(imports))
1318-
for impPath := range imports {
1319-
importPaths = append(importPaths, string(impPath))
1320-
}
1321-
sort.Strings(importPaths)
1322-
for _, importPath := range importPaths {
1323-
imp := imports[ImportPath(importPath)]
1318+
for importPath, imp := range moremaps.Sorted(imports) {
13241319
// TODO(rfindley): strength reduce the typerefs.Export API to guarantee
13251320
// that it only depends on these attributes of dependencies.
13261321
fmt.Fprintf(hasher, "import %s %s %s", importPath, imp.ID, imp.Name)
@@ -1431,13 +1426,8 @@ func localPackageKey(inputs *typeCheckInputs) file.Hash {
14311426
fmt.Fprintf(hasher, "go %s\n", inputs.goVersion)
14321427

14331428
// import map
1434-
importPaths := make([]string, 0, len(inputs.depsByImpPath))
1435-
for impPath := range inputs.depsByImpPath {
1436-
importPaths = append(importPaths, string(impPath))
1437-
}
1438-
sort.Strings(importPaths)
1439-
for _, impPath := range importPaths {
1440-
fmt.Fprintf(hasher, "import %s %s", impPath, string(inputs.depsByImpPath[ImportPath(impPath)]))
1429+
for impPath, depID := range moremaps.Sorted(inputs.depsByImpPath) {
1430+
fmt.Fprintf(hasher, "import %s %s", impPath, depID)
14411431
}
14421432

14431433
// file names and contents

gopls/internal/cache/typerefs/packageset.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ package typerefs
77
import (
88
"fmt"
99
"math/bits"
10-
"sort"
1110
"strings"
1211
"sync"
1312

1413
"golang.org/x/tools/gopls/internal/cache/metadata"
14+
"golang.org/x/tools/gopls/internal/util/moremaps"
1515
)
1616

1717
// PackageIndex stores common data to enable efficient representation of
@@ -123,13 +123,7 @@ func (s *PackageSet) Contains(id metadata.PackageID) bool {
123123

124124
// Elems calls f for each element of the set in ascending order.
125125
func (s *PackageSet) Elems(f func(IndexID)) {
126-
blockIndexes := make([]int, 0, len(s.sparse))
127-
for k := range s.sparse {
128-
blockIndexes = append(blockIndexes, k)
129-
}
130-
sort.Ints(blockIndexes)
131-
for _, i := range blockIndexes {
132-
v := s.sparse[i]
126+
for i, v := range moremaps.Sorted(s.sparse) {
133127
for b := 0; b < blockSize; b++ {
134128
if (v & (1 << b)) != 0 {
135129
f(IndexID(i*blockSize + b))

gopls/internal/debug/template_test.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"html/template"
1616
"os"
1717
"runtime"
18-
"sort"
1918
"strings"
2019
"testing"
2120

@@ -24,6 +23,7 @@ import (
2423
"golang.org/x/tools/gopls/internal/cache"
2524
"golang.org/x/tools/gopls/internal/debug"
2625
"golang.org/x/tools/gopls/internal/file"
26+
"golang.org/x/tools/gopls/internal/util/moremaps"
2727
"golang.org/x/tools/internal/testenv"
2828
)
2929

@@ -110,13 +110,7 @@ func TestTemplates(t *testing.T) {
110110
}
111111
}
112112
// now check all the known templates, in alphabetic order, for determinacy
113-
keys := []string{}
114-
for k := range templates {
115-
keys = append(keys, k)
116-
}
117-
sort.Strings(keys)
118-
for _, k := range keys {
119-
v := templates[k]
113+
for k, v := range moremaps.Sorted(templates) {
120114
// the FuncMap is an annoyance; should not be necessary
121115
if err := templatecheck.CheckHTML(v.tmpl, v.data); err != nil {
122116
t.Errorf("%s: %v", k, err)

gopls/internal/fuzzy/input_test.go

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package fuzzy_test
66

77
import (
88
"bytes"
9+
"slices"
910
"sort"
1011
"testing"
1112

@@ -83,17 +84,9 @@ func TestWordSplit(t *testing.T) {
8384
}
8485

8586
func diffStringLists(a, b []string) bool {
86-
if len(a) != len(b) {
87-
return false
88-
}
8987
sort.Strings(a)
9088
sort.Strings(b)
91-
for i := range a {
92-
if a[i] != b[i] {
93-
return false
94-
}
95-
}
96-
return true
89+
return slices.Equal(a, b)
9790
}
9891

9992
var lastSegmentSplitTests = []struct {

gopls/internal/golang/addtest.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717
"go/types"
1818
"os"
1919
"path/filepath"
20-
"sort"
2120
"strconv"
2221
"strings"
2322
"text/template"
@@ -29,6 +28,7 @@ import (
2928
"golang.org/x/tools/gopls/internal/cache/parsego"
3029
"golang.org/x/tools/gopls/internal/protocol"
3130
goplsastutil "golang.org/x/tools/gopls/internal/util/astutil"
31+
"golang.org/x/tools/gopls/internal/util/moremaps"
3232
"golang.org/x/tools/internal/imports"
3333
"golang.org/x/tools/internal/typesinternal"
3434
)
@@ -727,15 +727,10 @@ func AddTestForFunc(ctx context.Context, snapshot *cache.Snapshot, loc protocol.
727727
}
728728
} else {
729729
importsBuffer.WriteString("\nimport(")
730-
// Loop over the map in sorted order ensures deterministic outcome.
731-
paths := make([]string, 0, len(extraImports))
732-
for key := range extraImports {
733-
paths = append(paths, key)
734-
}
735-
sort.Strings(paths)
736-
for _, path := range paths {
730+
// Sort for determinism.
731+
for path, name := range moremaps.Sorted(extraImports) {
737732
importsBuffer.WriteString("\n\t")
738-
if name := extraImports[path]; name != "" {
733+
if name != "" {
739734
importsBuffer.WriteString(name + " ")
740735
}
741736
importsBuffer.WriteString(fmt.Sprintf("\"%s\"", path))

gopls/internal/util/moremaps/maps.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,30 @@ func ValueSlice[M ~map[K]V, K comparable, V any](m M) []V {
4242

4343
// SameKeys reports whether x and y have equal sets of keys.
4444
func SameKeys[K comparable, V1, V2 any](x map[K]V1, y map[K]V2) bool {
45-
if len(x) != len(y) {
46-
return false
47-
}
48-
for k := range x {
49-
if _, ok := y[k]; !ok {
50-
return false
51-
}
52-
}
53-
return true
45+
ignoreValues := func(V1, V2) bool { return true }
46+
return maps.EqualFunc(x, y, ignoreValues)
5447
}
5548

5649
// Sorted returns an iterator over the entries of m in key order.
5750
func Sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] {
51+
// TODO(adonovan): use maps.Sorted if proposal #68598 is accepted.
52+
return func(yield func(K, V) bool) {
53+
keys := KeySlice(m)
54+
slices.Sort(keys)
55+
for _, k := range keys {
56+
if !yield(k, m[k]) {
57+
break
58+
}
59+
}
60+
}
61+
}
62+
63+
// SortedFunc returns an iterator over the entries of m in key order.
64+
func SortedFunc[M ~map[K]V, K comparable, V any](m M, cmp func(x, y K) int) iter.Seq2[K, V] {
65+
// TODO(adonovan): use maps.SortedFunc if proposal #68598 is accepted.
5866
return func(yield func(K, V) bool) {
59-
keys := slices.Sorted(maps.Keys(m))
67+
keys := KeySlice(m)
68+
slices.SortFunc(keys, cmp)
6069
for _, k := range keys {
6170
if !yield(k, m[k]) {
6271
break

0 commit comments

Comments
 (0)