Skip to content

Commit 408d2e2

Browse files
committed
x/tools: remove workarounds for Go <1.23
Change-Id: I740769d6ed117bf140c9894b4464b3d3f7f326f1 Reviewed-on: https://go-review.googlesource.com/c/tools/+/653655 Auto-Submit: Alan Donovan <[email protected]> Reviewed-by: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 66eb306 commit 408d2e2

File tree

15 files changed

+48
-203
lines changed

15 files changed

+48
-203
lines changed

cmd/deadcode/deadcode.go

Lines changed: 7 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ import (
1515
"go/types"
1616
"io"
1717
"log"
18+
"maps"
1819
"os"
1920
"path/filepath"
2021
"regexp"
2122
"runtime"
2223
"runtime/pprof"
24+
"slices"
2325
"sort"
2426
"strings"
2527
"text/template"
@@ -290,9 +292,7 @@ func main() {
290292

291293
// Build array of jsonPackage objects.
292294
var packages []any
293-
pkgpaths := keys(byPkgPath)
294-
sort.Strings(pkgpaths)
295-
for _, pkgpath := range pkgpaths {
295+
for _, pkgpath := range slices.Sorted(maps.Keys(byPkgPath)) {
296296
if !filter.MatchString(pkgpath) {
297297
continue
298298
}
@@ -303,7 +303,7 @@ func main() {
303303
// declaration order. This tends to keep related
304304
// methods such as (T).Marshal and (*T).Unmarshal
305305
// together better than sorting.
306-
fns := keys(m)
306+
fns := slices.Collect(maps.Keys(m))
307307
sort.Slice(fns, func(i, j int) bool {
308308
xposn := prog.Fset.Position(fns[i].Pos())
309309
yposn := prog.Fset.Position(fns[j].Pos())
@@ -368,7 +368,7 @@ func prettyName(fn *ssa.Function, qualified bool) string {
368368
// anonymous?
369369
if fn.Parent() != nil {
370370
format(fn.Parent())
371-
i := index(fn.Parent().AnonFuncs, fn)
371+
i := slices.Index(fn.Parent().AnonFuncs, fn)
372372
fmt.Fprintf(&buf, "$%d", i+1)
373373
return
374374
}
@@ -427,7 +427,7 @@ func pathSearch(roots []*ssa.Function, res *rta.Result, targets map[*ssa.Functio
427427
// Sort roots into preferred order.
428428
importsTesting := func(fn *ssa.Function) bool {
429429
isTesting := func(p *types.Package) bool { return p.Path() == "testing" }
430-
return containsFunc(fn.Pkg.Pkg.Imports(), isTesting)
430+
return slices.ContainsFunc(fn.Pkg.Pkg.Imports(), isTesting)
431431
}
432432
sort.Slice(roots, func(i, j int) bool {
433433
x, y := roots[i], roots[j]
@@ -461,7 +461,7 @@ func pathSearch(roots []*ssa.Function, res *rta.Result, targets map[*ssa.Functio
461461
for {
462462
edge := seen[node]
463463
if edge == nil {
464-
reverse(path)
464+
slices.Reverse(path)
465465
return path
466466
}
467467
path = append(path, edge)
@@ -565,43 +565,3 @@ type jsonPosition struct {
565565
func (p jsonPosition) String() string {
566566
return fmt.Sprintf("%s:%d:%d", p.File, p.Line, p.Col)
567567
}
568-
569-
// -- from the future --
570-
571-
// TODO(adonovan): use go1.22's slices and maps packages.
572-
573-
func containsFunc[S ~[]E, E any](s S, f func(E) bool) bool {
574-
return indexFunc(s, f) >= 0
575-
}
576-
577-
func indexFunc[S ~[]E, E any](s S, f func(E) bool) int {
578-
for i := range s {
579-
if f(s[i]) {
580-
return i
581-
}
582-
}
583-
return -1
584-
}
585-
586-
func index[S ~[]E, E comparable](s S, v E) int {
587-
for i := range s {
588-
if v == s[i] {
589-
return i
590-
}
591-
}
592-
return -1
593-
}
594-
595-
func reverse[S ~[]E, E any](s S) {
596-
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
597-
s[i], s[j] = s[j], s[i]
598-
}
599-
}
600-
601-
func keys[M ~map[K]V, K comparable, V any](m M) []K {
602-
r := make([]K, 0, len(m))
603-
for k := range m {
604-
r = append(r, k)
605-
}
606-
return r
607-
}

go/analysis/analysistest/analysistest.go

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ package analysistest
77

88
import (
99
"bytes"
10-
"cmp"
1110
"fmt"
1211
"go/format"
1312
"go/token"
1413
"go/types"
1514
"log"
15+
"maps"
1616
"os"
1717
"path/filepath"
1818
"regexp"
@@ -215,7 +215,7 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
215215
// Because the checking is driven by original
216216
// filenames, there is no way to express that a fix
217217
// (e.g. extract declaration) creates a new file.
218-
for _, filename := range sortedKeys(allFilenames) {
218+
for _, filename := range slices.Sorted(maps.Keys(allFilenames)) {
219219
// Read the original file.
220220
content, err := os.ReadFile(filename)
221221
if err != nil {
@@ -266,7 +266,7 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
266266
// Form #2: all suggested fixes are represented by a single file.
267267
want := ar.Comment
268268
var accumulated []diff.Edit
269-
for _, message := range sortedKeys(fixEdits) {
269+
for _, message := range slices.Sorted(maps.Keys(fixEdits)) {
270270
for _, fix := range fixEdits[message] {
271271
accumulated = merge(filename, message, accumulated, fix[filename])
272272
}
@@ -768,13 +768,3 @@ func sanitize(gopath, filename string) string {
768768
prefix := gopath + string(os.PathSeparator) + "src" + string(os.PathSeparator)
769769
return filepath.ToSlash(strings.TrimPrefix(filename, prefix))
770770
}
771-
772-
// TODO(adonovan): use better stuff from go1.23.
773-
func sortedKeys[K cmp.Ordered, V any](m map[K]V) []K {
774-
keys := make([]K, 0, len(m))
775-
for k := range m {
776-
keys = append(keys, k)
777-
}
778-
slices.Sort(keys)
779-
return keys
780-
}

go/callgraph/vta/graph.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -633,12 +633,12 @@ func (b *builder) call(c ssa.CallInstruction) {
633633
return
634634
}
635635

636-
siteCallees(c, b.callees)(func(f *ssa.Function) bool {
636+
for f := range siteCallees(c, b.callees) {
637637
addArgumentFlows(b, c, f)
638638

639639
site, ok := c.(ssa.Value)
640640
if !ok {
641-
return true // go or defer
641+
continue // go or defer
642642
}
643643

644644
results := f.Signature.Results()
@@ -653,8 +653,7 @@ func (b *builder) call(c ssa.CallInstruction) {
653653
b.addInFlowEdge(resultVar{f: f, index: i}, local)
654654
}
655655
}
656-
return true
657-
})
656+
}
658657
}
659658

660659
func addArgumentFlows(b *builder, c ssa.CallInstruction, f *ssa.Function) {

go/callgraph/vta/propagation.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package vta
66

77
import (
88
"go/types"
9+
"iter"
910
"slices"
1011

1112
"golang.org/x/tools/go/callgraph/vta/internal/trie"
@@ -113,11 +114,9 @@ type propType struct {
113114
// the role of a map from nodes to a set of propTypes.
114115
type propTypeMap map[node]*trie.MutMap
115116

116-
// propTypes returns a go1.23 iterator for the propTypes associated with
117+
// propTypes returns an iterator for the propTypes associated with
117118
// node `n` in map `ptm`.
118-
func (ptm propTypeMap) propTypes(n node) func(yield func(propType) bool) {
119-
// TODO: when x/tools uses go1.23, change callers to use range-over-func
120-
// (https://go.dev/issue/65237).
119+
func (ptm propTypeMap) propTypes(n node) iter.Seq[propType] {
121120
return func(yield func(propType) bool) {
122121
if types := ptm[n]; types != nil {
123122
types.M.Range(func(_ uint64, elem any) bool {

go/callgraph/vta/propagation_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,9 @@ func nodeToTypeString(pMap propTypeMap) map[string]string {
9898
nodeToTypeStr := make(map[string]string)
9999
for node := range pMap {
100100
var propStrings []string
101-
pMap.propTypes(node)(func(prop propType) bool {
101+
for prop := range pMap.propTypes(node) {
102102
propStrings = append(propStrings, propTypeString(prop))
103-
return true
104-
})
103+
}
105104
sort.Strings(propStrings)
106105
nodeToTypeStr[node.String()] = strings.Join(propStrings, ";")
107106
}

go/callgraph/vta/utils.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package vta
66

77
import (
88
"go/types"
9+
"iter"
910

1011
"golang.org/x/tools/go/ssa"
1112
"golang.org/x/tools/internal/typeparams"
@@ -147,10 +148,8 @@ func sliceArrayElem(t types.Type) types.Type {
147148
}
148149
}
149150

150-
// siteCallees returns a go1.23 iterator for the callees for call site `c`.
151-
func siteCallees(c ssa.CallInstruction, callees calleesFunc) func(yield func(*ssa.Function) bool) {
152-
// TODO: when x/tools uses go1.23, change callers to use range-over-func
153-
// (https://go.dev/issue/65237).
151+
// siteCallees returns an iterator for the callees for call site `c`.
152+
func siteCallees(c ssa.CallInstruction, callees calleesFunc) iter.Seq[*ssa.Function] {
154153
return func(yield func(*ssa.Function) bool) {
155154
for _, callee := range callees(c) {
156155
if !yield(callee) {

go/callgraph/vta/vta.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,11 @@ func (c *constructor) resolves(call ssa.CallInstruction) []*ssa.Function {
126126
// Cover the case of dynamic higher-order and interface calls.
127127
var res []*ssa.Function
128128
resolved := resolve(call, c.types, c.cache)
129-
siteCallees(call, c.callees)(func(f *ssa.Function) bool {
129+
for f := range siteCallees(call, c.callees) {
130130
if _, ok := resolved[f]; ok {
131131
res = append(res, f)
132132
}
133-
return true
134-
})
133+
}
135134
return res
136135
}
137136

@@ -140,12 +139,11 @@ func (c *constructor) resolves(call ssa.CallInstruction) []*ssa.Function {
140139
func resolve(c ssa.CallInstruction, types propTypeMap, cache methodCache) map[*ssa.Function]empty {
141140
fns := make(map[*ssa.Function]empty)
142141
n := local{val: c.Common().Value}
143-
types.propTypes(n)(func(p propType) bool {
142+
for p := range types.propTypes(n) {
144143
for _, f := range propFunc(p, c, cache) {
145144
fns[f] = empty{}
146145
}
147-
return true
148-
})
146+
}
149147
return fns
150148
}
151149

go/ssa/builder.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ import (
8282
"runtime"
8383
"sync"
8484

85+
"slices"
86+
8587
"golang.org/x/tools/internal/typeparams"
8688
"golang.org/x/tools/internal/versions"
8789
)
@@ -2021,8 +2023,8 @@ func (b *builder) forStmtGo122(fn *Function, s *ast.ForStmt, label *lblock) {
20212023
// Remove instructions for phi, load, and store.
20222024
// lift() will remove the unused i_next *Alloc.
20232025
isDead := func(i Instruction) bool { return dead[i] }
2024-
loop.Instrs = removeInstrsIf(loop.Instrs, isDead)
2025-
post.Instrs = removeInstrsIf(post.Instrs, isDead)
2026+
loop.Instrs = slices.DeleteFunc(loop.Instrs, isDead)
2027+
post.Instrs = slices.DeleteFunc(post.Instrs, isDead)
20262028
}
20272029
}
20282030

go/ssa/lift.go

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import (
4343
"go/token"
4444
"math/big"
4545
"os"
46+
"slices"
4647

4748
"golang.org/x/tools/internal/typeparams"
4849
)
@@ -105,23 +106,7 @@ func buildDomFrontier(fn *Function) domFrontier {
105106
}
106107

107108
func removeInstr(refs []Instruction, instr Instruction) []Instruction {
108-
return removeInstrsIf(refs, func(i Instruction) bool { return i == instr })
109-
}
110-
111-
func removeInstrsIf(refs []Instruction, p func(Instruction) bool) []Instruction {
112-
// TODO(taking): replace with go1.22 slices.DeleteFunc.
113-
i := 0
114-
for _, ref := range refs {
115-
if p(ref) {
116-
continue
117-
}
118-
refs[i] = ref
119-
i++
120-
}
121-
for j := i; j != len(refs); j++ {
122-
refs[j] = nil // aid GC
123-
}
124-
return refs[:i]
109+
return slices.DeleteFunc(refs, func(i Instruction) bool { return i == instr })
125110
}
126111

127112
// lift replaces local and new Allocs accessed only with

go/types/internal/play/play.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -430,12 +430,3 @@ textarea { width: 6in; }
430430
body { color: gray; }
431431
div#out { font-family: monospace; font-size: 80%; }
432432
`
433-
434-
// TODO(adonovan): use go1.21 built-in.
435-
func min(x, y int) int {
436-
if x < y {
437-
return x
438-
} else {
439-
return y
440-
}
441-
}

gopls/internal/cache/parsego/parse.go

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727
"golang.org/x/tools/gopls/internal/label"
2828
"golang.org/x/tools/gopls/internal/protocol"
2929
"golang.org/x/tools/gopls/internal/util/astutil"
30-
"golang.org/x/tools/gopls/internal/util/bug"
3130
"golang.org/x/tools/gopls/internal/util/safetoken"
3231
"golang.org/x/tools/internal/astutil/cursor"
3332
"golang.org/x/tools/internal/diff"
@@ -65,39 +64,8 @@ func Parse(ctx context.Context, fset *token.FileSet, uri protocol.DocumentURI, s
6564
}
6665
// Inv: file != nil.
6766

68-
// Workaround for #70162 (missing File{Start,End} when
69-
// parsing empty file) with go1.23.
70-
//
71-
// When parsing an empty file, or one without a valid
72-
// package declaration, the go1.23 parser bails out before
73-
// setting FileStart and End.
74-
//
75-
// This leaves us no way to find the original
76-
// token.File that ParseFile created, so as a
77-
// workaround, we recreate the token.File, and
78-
// populate the FileStart and FileEnd fields.
79-
//
80-
// See also #53202.
8167
tokenFile := func(file *ast.File) *token.File {
82-
tok := fset.File(file.FileStart)
83-
if tok == nil {
84-
// Invalid File.FileStart (also File.{Package,Name.Pos}).
85-
if file.Package.IsValid() {
86-
bug.Report("ast.File has valid Package but no FileStart")
87-
}
88-
if file.Name.Pos().IsValid() {
89-
bug.Report("ast.File has valid Name.Pos but no FileStart")
90-
}
91-
tok = fset.AddFile(uri.Path(), -1, len(src))
92-
tok.SetLinesForContent(src)
93-
// If the File contained any valid token.Pos values,
94-
// they would all be invalid wrt the new token.File,
95-
// but we have established that it lacks FileStart,
96-
// Package, and Name.Pos.
97-
file.FileStart = token.Pos(tok.Base())
98-
file.FileEnd = token.Pos(tok.Base() + tok.Size())
99-
}
100-
return tok
68+
return fset.File(file.FileStart)
10169
}
10270

10371
tok := tokenFile(file)

0 commit comments

Comments
 (0)