Skip to content

Commit f3a6b96

Browse files
xieyuschengopherbot
authored andcommitted
gopls/internal/analysis/modernize: add modernizer for WaitGroup.Go
This CL supports a modernizer to replace old complex usages of WaitGroup by WaitGroup.Go from go1.25. Fixes: golang/go#73059 Change-Id: I8e2f8df0cca0fae4996d2a46c6a8229cf1d37e2c Reviewed-on: https://go-review.googlesource.com/c/tools/+/661775 Reviewed-by: Alan Donovan <[email protected]> Auto-Submit: Alan Donovan <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Carlos Amedee <[email protected]>
1 parent 5fba861 commit f3a6b96

12 files changed

+522
-3
lines changed

Diff for: gopls/doc/analyzers.md

+2
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,8 @@ Categories of modernize diagnostic:
553553
- stringscutprefix: replace some uses of HasPrefix followed by TrimPrefix with CutPrefix,
554554
added to the strings package in go1.20.
555555

556+
- waitgroup: replace old complex usages of sync.WaitGroup by less complex WaitGroup.Go method in go1.25.
557+
556558
Default: on.
557559

558560
Package documentation: [modernize](https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize)

Diff for: gopls/internal/analysis/modernize/doc.go

+2
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,6 @@
8585
//
8686
// - stringscutprefix: replace some uses of HasPrefix followed by TrimPrefix with CutPrefix,
8787
// added to the strings package in go1.20.
88+
//
89+
// - waitgroup: replace old complex usages of sync.WaitGroup by less complex WaitGroup.Go method in go1.25.
8890
package modernize

Diff for: gopls/internal/analysis/modernize/modernize.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ func run(pass *analysis.Pass) (any, error) {
9393
stringsseq(pass)
9494
sortslice(pass)
9595
testingContext(pass)
96+
waitgroup(pass)
9697

9798
// TODO(adonovan): opt: interleave these micro-passes within a single inspection.
9899

@@ -121,7 +122,12 @@ func formatExprs(fset *token.FileSet, exprs []ast.Expr) string {
121122

122123
// isZeroIntLiteral reports whether e is an integer whose value is 0.
123124
func isZeroIntLiteral(info *types.Info, e ast.Expr) bool {
124-
return info.Types[e].Value == constant.MakeInt64(0)
125+
return isIntLiteral(info, e, 0)
126+
}
127+
128+
// isIntLiteral reports whether e is an integer with given value.
129+
func isIntLiteral(info *types.Info, e ast.Expr, n int64) bool {
130+
return info.Types[e].Value == constant.MakeInt64(n)
125131
}
126132

127133
// filesUsing returns a cursor for each *ast.File in the inspector

Diff for: gopls/internal/analysis/modernize/modernize_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ func Test(t *testing.T) {
2929
"fieldsseq",
3030
"sortslice",
3131
"testingcontext",
32+
"waitgroup",
3233
)
3334
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package waitgroup
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
)
7+
8+
// supported case for pattern 1.
9+
func _() {
10+
var wg sync.WaitGroup
11+
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
12+
go func() {
13+
defer wg.Done()
14+
fmt.Println()
15+
}()
16+
17+
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
18+
go func() {
19+
defer wg.Done()
20+
}()
21+
22+
for range 10 {
23+
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
24+
go func() {
25+
defer wg.Done()
26+
fmt.Println()
27+
}()
28+
}
29+
}
30+
31+
// supported case for pattern 2.
32+
func _() {
33+
var wg sync.WaitGroup
34+
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
35+
go func() {
36+
fmt.Println()
37+
wg.Done()
38+
}()
39+
40+
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
41+
go func() {
42+
wg.Done()
43+
}()
44+
45+
for range 10 {
46+
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
47+
go func() {
48+
fmt.Println()
49+
wg.Done()
50+
}()
51+
}
52+
}
53+
54+
// this function puts some wrong usages but waitgroup modernizer will still offer fixes.
55+
func _() {
56+
var wg sync.WaitGroup
57+
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
58+
go func() {
59+
defer wg.Done()
60+
defer wg.Done()
61+
fmt.Println()
62+
}()
63+
64+
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
65+
go func() {
66+
defer wg.Done()
67+
fmt.Println()
68+
wg.Done()
69+
}()
70+
71+
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
72+
go func() {
73+
fmt.Println()
74+
wg.Done()
75+
wg.Done()
76+
}()
77+
}
78+
79+
// this function puts the unsupported cases of pattern 1.
80+
func _() {
81+
var wg sync.WaitGroup
82+
wg.Add(1)
83+
go func() {}()
84+
85+
wg.Add(1)
86+
go func(i int) {
87+
defer wg.Done()
88+
fmt.Println(i)
89+
}(1)
90+
91+
wg.Add(1)
92+
go func() {
93+
fmt.Println()
94+
defer wg.Done()
95+
}()
96+
97+
wg.Add(1)
98+
go func() { // noop: no wg.Done call inside function body.
99+
fmt.Println()
100+
}()
101+
102+
go func() { // noop: no Add call before this go stmt.
103+
defer wg.Done()
104+
fmt.Println()
105+
}()
106+
107+
wg.Add(2) // noop: only support Add(1).
108+
go func() {
109+
defer wg.Done()
110+
}()
111+
112+
var wg1 sync.WaitGroup
113+
wg1.Add(1) // noop: Add and Done should be the same object.
114+
go func() {
115+
defer wg.Done()
116+
fmt.Println()
117+
}()
118+
119+
wg.Add(1) // noop: Add and Done should be the same object.
120+
go func() {
121+
defer wg1.Done()
122+
fmt.Println()
123+
}()
124+
}
125+
126+
// this function puts the unsupported cases of pattern 2.
127+
func _() {
128+
var wg sync.WaitGroup
129+
wg.Add(1)
130+
go func() {
131+
wg.Done()
132+
fmt.Println()
133+
}()
134+
135+
go func() { // noop: no Add call before this go stmt.
136+
fmt.Println()
137+
wg.Done()
138+
}()
139+
140+
var wg1 sync.WaitGroup
141+
wg1.Add(1) // noop: Add and Done should be the same object.
142+
go func() {
143+
fmt.Println()
144+
wg.Done()
145+
}()
146+
147+
wg.Add(1) // noop: Add and Done should be the same object.
148+
go func() {
149+
fmt.Println()
150+
wg1.Done()
151+
}()
152+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package waitgroup
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
)
7+
8+
// supported case for pattern 1.
9+
func _() {
10+
var wg sync.WaitGroup
11+
// want "Goroutine creation can be simplified using WaitGroup.Go"
12+
wg.Go(func() {
13+
fmt.Println()
14+
})
15+
16+
// want "Goroutine creation can be simplified using WaitGroup.Go"
17+
wg.Go(func() {
18+
})
19+
20+
for range 10 {
21+
// want "Goroutine creation can be simplified using WaitGroup.Go"
22+
wg.Go(func() {
23+
fmt.Println()
24+
})
25+
}
26+
}
27+
28+
// supported case for pattern 2.
29+
func _() {
30+
var wg sync.WaitGroup
31+
// want "Goroutine creation can be simplified using WaitGroup.Go"
32+
wg.Go(func() {
33+
fmt.Println()
34+
})
35+
36+
// want "Goroutine creation can be simplified using WaitGroup.Go"
37+
wg.Go(func() {
38+
})
39+
40+
for range 10 {
41+
// want "Goroutine creation can be simplified using WaitGroup.Go"
42+
wg.Go(func() {
43+
fmt.Println()
44+
})
45+
}
46+
}
47+
48+
// this function puts some wrong usages but waitgroup modernizer will still offer fixes.
49+
func _() {
50+
var wg sync.WaitGroup
51+
// want "Goroutine creation can be simplified using WaitGroup.Go"
52+
wg.Go(func() {
53+
defer wg.Done()
54+
fmt.Println()
55+
})
56+
57+
// want "Goroutine creation can be simplified using WaitGroup.Go"
58+
wg.Go(func() {
59+
fmt.Println()
60+
wg.Done()
61+
})
62+
63+
// want "Goroutine creation can be simplified using WaitGroup.Go"
64+
wg.Go(func() {
65+
fmt.Println()
66+
wg.Done()
67+
})
68+
}
69+
70+
// this function puts the unsupported cases of pattern 1.
71+
func _() {
72+
var wg sync.WaitGroup
73+
wg.Add(1)
74+
go func() {}()
75+
76+
wg.Add(1)
77+
go func(i int) {
78+
defer wg.Done()
79+
fmt.Println(i)
80+
}(1)
81+
82+
wg.Add(1)
83+
go func() {
84+
fmt.Println()
85+
defer wg.Done()
86+
}()
87+
88+
wg.Add(1)
89+
go func() { // noop: no wg.Done call inside function body.
90+
fmt.Println()
91+
}()
92+
93+
go func() { // noop: no Add call before this go stmt.
94+
defer wg.Done()
95+
fmt.Println()
96+
}()
97+
98+
wg.Add(2) // noop: only support Add(1).
99+
go func() {
100+
defer wg.Done()
101+
}()
102+
103+
var wg1 sync.WaitGroup
104+
wg1.Add(1) // noop: Add and Done should be the same object.
105+
go func() {
106+
defer wg.Done()
107+
fmt.Println()
108+
}()
109+
110+
wg.Add(1) // noop: Add and Done should be the same object.
111+
go func() {
112+
defer wg1.Done()
113+
fmt.Println()
114+
}()
115+
}
116+
117+
// this function puts the unsupported cases of pattern 2.
118+
func _() {
119+
var wg sync.WaitGroup
120+
wg.Add(1)
121+
go func() {
122+
wg.Done()
123+
fmt.Println()
124+
}()
125+
126+
go func() { // noop: no Add call before this go stmt.
127+
fmt.Println()
128+
wg.Done()
129+
}()
130+
131+
var wg1 sync.WaitGroup
132+
wg1.Add(1) // noop: Add and Done should be the same object.
133+
go func() {
134+
fmt.Println()
135+
wg.Done()
136+
}()
137+
138+
wg.Add(1) // noop: Add and Done should be the same object.
139+
go func() {
140+
fmt.Println()
141+
wg1.Done()
142+
}()
143+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package waitgroup
2+
3+
import (
4+
"fmt"
5+
sync1 "sync"
6+
)
7+
8+
func _() {
9+
var wg sync1.WaitGroup
10+
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
11+
go func() {
12+
defer wg.Done()
13+
fmt.Println()
14+
}()
15+
16+
wg.Add(1) // want "Goroutine creation can be simplified using WaitGroup.Go"
17+
go func() {
18+
fmt.Println()
19+
wg.Done()
20+
}()
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package waitgroup
2+
3+
import (
4+
"fmt"
5+
sync1 "sync"
6+
)
7+
8+
func _() {
9+
var wg sync1.WaitGroup
10+
// want "Goroutine creation can be simplified using WaitGroup.Go"
11+
wg.Go(func() {
12+
fmt.Println()
13+
})
14+
15+
// want "Goroutine creation can be simplified using WaitGroup.Go"
16+
wg.Go(func() {
17+
fmt.Println()
18+
})
19+
}

0 commit comments

Comments
 (0)