Skip to content

Commit 0e169c9

Browse files
committed
feat: add exptostd linter
1 parent 8e47515 commit 0e169c9

13 files changed

+436
-0
lines changed

.golangci.next.reference.yml

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ linters:
3535
- exhaustive
3636
- exhaustruct
3737
- exportloopref
38+
- exptostd
3839
- fatcontext
3940
- forbidigo
4041
- forcetypeassert
@@ -153,6 +154,7 @@ linters:
153154
- exhaustive
154155
- exhaustruct
155156
- exportloopref
157+
- exptostd
156158
- fatcontext
157159
- forbidigo
158160
- forcetypeassert

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ require (
6565
github.com/kunwardeep/paralleltest v1.0.10
6666
github.com/kyoh86/exportloopref v0.1.11
6767
github.com/lasiar/canonicalheader v1.1.2
68+
github.com/ldez/exptostd v0.1.0
6869
github.com/ldez/gomoddirectives v0.6.0
6970
github.com/ldez/grignotin v0.7.0
7071
github.com/ldez/tagliatelle v0.7.1

go.sum

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jsonschema/golangci.next.jsonschema.json

+1
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@
350350
"exhaustive",
351351
"exhaustruct",
352352
"exportloopref",
353+
"exptostd",
353354
"fatcontext",
354355
"forbidigo",
355356
"forcetypeassert",

pkg/golinters/exptostd/exptostd.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package exptostd
2+
3+
import (
4+
"github.com/ldez/exptostd"
5+
"golang.org/x/tools/go/analysis"
6+
7+
"github.com/golangci/golangci-lint/pkg/goanalysis"
8+
)
9+
10+
func New() *goanalysis.Linter {
11+
a := exptostd.NewAnalyzer()
12+
13+
return goanalysis.NewLinter(
14+
a.Name,
15+
a.Doc,
16+
[]*analysis.Analyzer{a},
17+
nil,
18+
).WithLoadMode(goanalysis.LoadModeTypesInfo)
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package exptostd
2+
3+
import (
4+
"testing"
5+
6+
"github.com/golangci/golangci-lint/test/testshared/integration"
7+
)
8+
9+
func TestFromTestdata(t *testing.T) {
10+
integration.RunTestdata(t)
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//golangcitest:args -Eexptostd
2+
package testdata
3+
4+
import (
5+
"fmt"
6+
7+
"golang.org/x/exp/maps"
8+
"golang.org/x/exp/slices"
9+
)
10+
11+
func _(m, a map[string]string) {
12+
maps.Clone(m) // want `golang.org/x/exp/maps.Clone\(\) can be replaced by maps.Clone\(\)`
13+
14+
maps.Equal(m, a) // want `golang.org/x/exp/maps.Equal\(\) can be replaced by maps.Equal\(\)`
15+
16+
maps.EqualFunc(m, a, func(i, j string) bool { // want `golang.org/x/exp/maps.EqualFunc\(\) can be replaced by maps.EqualFunc\(\)`
17+
return true
18+
})
19+
20+
maps.Copy(m, a) // want `golang.org/x/exp/maps.Copy\(\) can be replaced by maps.Copy\(\)`
21+
22+
maps.DeleteFunc(m, func(_, _ string) bool { // want `golang.org/x/exp/maps.DeleteFunc\(\) can be replaced by maps.DeleteFunc\(\)`
23+
return true
24+
})
25+
26+
maps.Clear(m) // want `golang.org/x/exp/maps.Clear\(\) can be replaced by clear\(\)`
27+
28+
fmt.Println("Hello")
29+
}
30+
31+
func _(a, b []string) {
32+
slices.Equal(a, b) // want `golang.org/x/exp/slices\.Equal\(\) can be replaced by slices\.Equal\(\)`
33+
slices.EqualFunc(a, b, func(_ string, _ string) bool { // want `golang.org/x/exp/slices\.EqualFunc\(\) can be replaced by slices\.EqualFunc\(\)`
34+
return true
35+
})
36+
slices.Compare(a, b) // want `golang.org/x/exp/slices\.Compare\(\) can be replaced by slices\.Compare\(\)`
37+
slices.CompareFunc(a, b, func(_ string, _ string) int { // want `golang.org/x/exp/slices\.CompareFunc\(\) can be replaced by slices\.CompareFunc\(\)`
38+
return 0
39+
})
40+
slices.Index(a, "a") // want `golang.org/x/exp/slices\.Index\(\) can be replaced by slices\.Index\(\)`
41+
slices.IndexFunc(a, func(_ string) bool { // want `golang.org/x/exp/slices\.IndexFunc\(\) can be replaced by slices\.IndexFunc\(\)`
42+
return true
43+
})
44+
slices.Contains(a, "a") // want `golang.org/x/exp/slices\.Contains\(\) can be replaced by slices\.Contains\(\)`
45+
slices.ContainsFunc(a, func(_ string) bool { // want `golang.org/x/exp/slices\.ContainsFunc\(\) can be replaced by slices\.ContainsFunc\(\)`
46+
return true
47+
})
48+
slices.Insert(a, 0, "a", "b") // want `golang.org/x/exp/slices\.Insert\(\) can be replaced by slices\.Insert\(\)`
49+
slices.Delete(a, 0, 1) // want `golang.org/x/exp/slices\.Delete\(\) can be replaced by slices\.Delete\(\)`
50+
slices.DeleteFunc(a, func(_ string) bool { // want `golang.org/x/exp/slices\.DeleteFunc\(\) can be replaced by slices\.DeleteFunc\(\)`
51+
return true
52+
})
53+
slices.Replace(a, 0, 1, "a") // want `golang.org/x/exp/slices\.Replace\(\) can be replaced by slices\.Replace\(\)`
54+
slices.Clone(a) // want `golang.org/x/exp/slices\.Clone\(\) can be replaced by slices\.Clone\(\)`
55+
slices.Compact(a) // want `golang.org/x/exp/slices\.Compact\(\) can be replaced by slices\.Compact\(\)`
56+
slices.CompactFunc(a, func(_ string, _ string) bool { // want `golang.org/x/exp/slices\.CompactFunc\(\) can be replaced by slices\.CompactFunc\(\)`
57+
return true
58+
})
59+
slices.Grow(a, 2) // want `golang.org/x/exp/slices\.Grow\(\) can be replaced by slices\.Grow\(\)`
60+
slices.Clip(a) // want `golang.org/x/exp/slices\.Clip\(\) can be replaced by slices\.Clip\(\)`
61+
slices.Reverse(a) // want `golang.org/x/exp/slices\.Reverse\(\) can be replaced by slices\.Reverse\(\)`
62+
slices.Sort(a) // want `golang.org/x/exp/slices\.Sort\(\) can be replaced by slices\.Sort\(\)`
63+
slices.SortFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.SortFunc\(\) can be replaced by slices\.SortFunc\(\)`
64+
return 0
65+
})
66+
slices.SortStableFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.SortStableFunc\(\) can be replaced by slices\.SortStableFunc\(\)`
67+
return 0
68+
})
69+
slices.IsSorted(a) // want `golang.org/x/exp/slices\.IsSorted\(\) can be replaced by slices\.IsSorted\(\)`
70+
slices.IsSortedFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.IsSortedFunc\(\) can be replaced by slices\.IsSortedFunc\(\)`
71+
return 0
72+
})
73+
slices.Min(a) // want `golang.org/x/exp/slices\.Min\(\) can be replaced by slices\.Min\(\)`
74+
slices.MinFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.MinFunc\(\) can be replaced by slices\.MinFunc\(\)`
75+
return 0
76+
})
77+
slices.Max(a) // want `golang.org/x/exp/slices\.Max\(\) can be replaced by slices\.Max\(\)`
78+
slices.MaxFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.MaxFunc\(\) can be replaced by slices\.MaxFunc\(\)`
79+
return 0
80+
})
81+
slices.BinarySearch(a, "a") // want `golang.org/x/exp/slices\.BinarySearch\(\) can be replaced by slices\.BinarySearch\(\)`
82+
slices.BinarySearchFunc(a, b, func(_ string, _ []string) int { // want `golang.org/x/exp/slices\.BinarySearchFunc\(\) can be replaced by slices\.BinarySearchFunc\(\)`
83+
return 0
84+
})
85+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//golangcitest:args -Eexptostd
2+
package testdata
3+
4+
/*
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
8+
void myprint(char* s) {
9+
printf("%d\n", s);
10+
}
11+
*/
12+
import "C"
13+
14+
import (
15+
"fmt"
16+
"unsafe"
17+
18+
"golang.org/x/exp/maps"
19+
"golang.org/x/exp/slices"
20+
)
21+
22+
func _() {
23+
cs := C.CString("Hello from stdio\n")
24+
C.myprint(cs)
25+
C.free(unsafe.Pointer(cs))
26+
}
27+
28+
func _(m, a map[string]string) {
29+
maps.Clone(m) // want `golang.org/x/exp/maps.Clone\(\) can be replaced by maps.Clone\(\)`
30+
31+
maps.Equal(m, a) // want `golang.org/x/exp/maps.Equal\(\) can be replaced by maps.Equal\(\)`
32+
33+
maps.EqualFunc(m, a, func(i, j string) bool { // want `golang.org/x/exp/maps.EqualFunc\(\) can be replaced by maps.EqualFunc\(\)`
34+
return true
35+
})
36+
37+
maps.Copy(m, a) // want `golang.org/x/exp/maps.Copy\(\) can be replaced by maps.Copy\(\)`
38+
39+
maps.DeleteFunc(m, func(_, _ string) bool { // want `golang.org/x/exp/maps.DeleteFunc\(\) can be replaced by maps.DeleteFunc\(\)`
40+
return true
41+
})
42+
43+
maps.Clear(m) // want `golang.org/x/exp/maps.Clear\(\) can be replaced by clear\(\)`
44+
45+
fmt.Println("Hello")
46+
}
47+
48+
func _(a, b []string) {
49+
slices.Equal(a, b) // want `golang.org/x/exp/slices\.Equal\(\) can be replaced by slices\.Equal\(\)`
50+
slices.EqualFunc(a, b, func(_ string, _ string) bool { // want `golang.org/x/exp/slices\.EqualFunc\(\) can be replaced by slices\.EqualFunc\(\)`
51+
return true
52+
})
53+
slices.Compare(a, b) // want `golang.org/x/exp/slices\.Compare\(\) can be replaced by slices\.Compare\(\)`
54+
slices.CompareFunc(a, b, func(_ string, _ string) int { // want `golang.org/x/exp/slices\.CompareFunc\(\) can be replaced by slices\.CompareFunc\(\)`
55+
return 0
56+
})
57+
slices.Index(a, "a") // want `golang.org/x/exp/slices\.Index\(\) can be replaced by slices\.Index\(\)`
58+
slices.IndexFunc(a, func(_ string) bool { // want `golang.org/x/exp/slices\.IndexFunc\(\) can be replaced by slices\.IndexFunc\(\)`
59+
return true
60+
})
61+
slices.Contains(a, "a") // want `golang.org/x/exp/slices\.Contains\(\) can be replaced by slices\.Contains\(\)`
62+
slices.ContainsFunc(a, func(_ string) bool { // want `golang.org/x/exp/slices\.ContainsFunc\(\) can be replaced by slices\.ContainsFunc\(\)`
63+
return true
64+
})
65+
slices.Insert(a, 0, "a", "b") // want `golang.org/x/exp/slices\.Insert\(\) can be replaced by slices\.Insert\(\)`
66+
slices.Delete(a, 0, 1) // want `golang.org/x/exp/slices\.Delete\(\) can be replaced by slices\.Delete\(\)`
67+
slices.DeleteFunc(a, func(_ string) bool { // want `golang.org/x/exp/slices\.DeleteFunc\(\) can be replaced by slices\.DeleteFunc\(\)`
68+
return true
69+
})
70+
slices.Replace(a, 0, 1, "a") // want `golang.org/x/exp/slices\.Replace\(\) can be replaced by slices\.Replace\(\)`
71+
slices.Clone(a) // want `golang.org/x/exp/slices\.Clone\(\) can be replaced by slices\.Clone\(\)`
72+
slices.Compact(a) // want `golang.org/x/exp/slices\.Compact\(\) can be replaced by slices\.Compact\(\)`
73+
slices.CompactFunc(a, func(_ string, _ string) bool { // want `golang.org/x/exp/slices\.CompactFunc\(\) can be replaced by slices\.CompactFunc\(\)`
74+
return true
75+
})
76+
slices.Grow(a, 2) // want `golang.org/x/exp/slices\.Grow\(\) can be replaced by slices\.Grow\(\)`
77+
slices.Clip(a) // want `golang.org/x/exp/slices\.Clip\(\) can be replaced by slices\.Clip\(\)`
78+
slices.Reverse(a) // want `golang.org/x/exp/slices\.Reverse\(\) can be replaced by slices\.Reverse\(\)`
79+
slices.Sort(a) // want `golang.org/x/exp/slices\.Sort\(\) can be replaced by slices\.Sort\(\)`
80+
slices.SortFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.SortFunc\(\) can be replaced by slices\.SortFunc\(\)`
81+
return 0
82+
})
83+
slices.SortStableFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.SortStableFunc\(\) can be replaced by slices\.SortStableFunc\(\)`
84+
return 0
85+
})
86+
slices.IsSorted(a) // want `golang.org/x/exp/slices\.IsSorted\(\) can be replaced by slices\.IsSorted\(\)`
87+
slices.IsSortedFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.IsSortedFunc\(\) can be replaced by slices\.IsSortedFunc\(\)`
88+
return 0
89+
})
90+
slices.Min(a) // want `golang.org/x/exp/slices\.Min\(\) can be replaced by slices\.Min\(\)`
91+
slices.MinFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.MinFunc\(\) can be replaced by slices\.MinFunc\(\)`
92+
return 0
93+
})
94+
slices.Max(a) // want `golang.org/x/exp/slices\.Max\(\) can be replaced by slices\.Max\(\)`
95+
slices.MaxFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.MaxFunc\(\) can be replaced by slices\.MaxFunc\(\)`
96+
return 0
97+
})
98+
slices.BinarySearch(a, "a") // want `golang.org/x/exp/slices\.BinarySearch\(\) can be replaced by slices\.BinarySearch\(\)`
99+
slices.BinarySearchFunc(a, b, func(_ string, _ []string) int { // want `golang.org/x/exp/slices\.BinarySearchFunc\(\) can be replaced by slices\.BinarySearchFunc\(\)`
100+
return 0
101+
})
102+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//go:build go1.23
2+
3+
//golangcitest:args -Eexptostd
4+
package testdata
5+
6+
import (
7+
"fmt"
8+
9+
"golang.org/x/exp/maps"
10+
"golang.org/x/exp/slices"
11+
)
12+
13+
func _(m, a map[string]string) {
14+
maps.Clone(m) // want `golang.org/x/exp/maps.Clone\(\) can be replaced by maps.Clone\(\)`
15+
16+
maps.Keys(m) // want `golang.org/x/exp/maps.Keys\(\) can be replaced by slices.Collect\(maps.Keys\(\)\)`
17+
18+
maps.Values(m) // want `golang.org/x/exp/maps.Values\(\) can be replaced by slices.Collect\(maps.Keys\(\)\)`
19+
20+
maps.Equal(m, a) // want `golang.org/x/exp/maps.Equal\(\) can be replaced by maps.Equal\(\)`
21+
22+
maps.EqualFunc(m, a, func(i, j string) bool { // want `golang.org/x/exp/maps.EqualFunc\(\) can be replaced by maps.EqualFunc\(\)`
23+
return true
24+
})
25+
26+
maps.Copy(m, a) // want `golang.org/x/exp/maps.Copy\(\) can be replaced by maps.Copy\(\)`
27+
28+
maps.DeleteFunc(m, func(_, _ string) bool { // want `golang.org/x/exp/maps.DeleteFunc\(\) can be replaced by maps.DeleteFunc\(\)`
29+
return true
30+
})
31+
32+
maps.Clear(m) // want `golang.org/x/exp/maps.Clear\(\) can be replaced by clear\(\)`
33+
34+
fmt.Println("Hello")
35+
}
36+
37+
func _(a, b []string) {
38+
slices.Equal(a, b) // want `golang.org/x/exp/slices\.Equal\(\) can be replaced by slices\.Equal\(\)`
39+
slices.EqualFunc(a, b, func(_ string, _ string) bool { // want `golang.org/x/exp/slices\.EqualFunc\(\) can be replaced by slices\.EqualFunc\(\)`
40+
return true
41+
})
42+
slices.Compare(a, b) // want `golang.org/x/exp/slices\.Compare\(\) can be replaced by slices\.Compare\(\)`
43+
slices.CompareFunc(a, b, func(_ string, _ string) int { // want `golang.org/x/exp/slices\.CompareFunc\(\) can be replaced by slices\.CompareFunc\(\)`
44+
return 0
45+
})
46+
slices.Index(a, "a") // want `golang.org/x/exp/slices\.Index\(\) can be replaced by slices\.Index\(\)`
47+
slices.IndexFunc(a, func(_ string) bool { // want `golang.org/x/exp/slices\.IndexFunc\(\) can be replaced by slices\.IndexFunc\(\)`
48+
return true
49+
})
50+
slices.Contains(a, "a") // want `golang.org/x/exp/slices\.Contains\(\) can be replaced by slices\.Contains\(\)`
51+
slices.ContainsFunc(a, func(_ string) bool { // want `golang.org/x/exp/slices\.ContainsFunc\(\) can be replaced by slices\.ContainsFunc\(\)`
52+
return true
53+
})
54+
slices.Insert(a, 0, "a", "b") // want `golang.org/x/exp/slices\.Insert\(\) can be replaced by slices\.Insert\(\)`
55+
slices.Delete(a, 0, 1) // want `golang.org/x/exp/slices\.Delete\(\) can be replaced by slices\.Delete\(\)`
56+
slices.DeleteFunc(a, func(_ string) bool { // want `golang.org/x/exp/slices\.DeleteFunc\(\) can be replaced by slices\.DeleteFunc\(\)`
57+
return true
58+
})
59+
slices.Replace(a, 0, 1, "a") // want `golang.org/x/exp/slices\.Replace\(\) can be replaced by slices\.Replace\(\)`
60+
slices.Clone(a) // want `golang.org/x/exp/slices\.Clone\(\) can be replaced by slices\.Clone\(\)`
61+
slices.Compact(a) // want `golang.org/x/exp/slices\.Compact\(\) can be replaced by slices\.Compact\(\)`
62+
slices.CompactFunc(a, func(_ string, _ string) bool { // want `golang.org/x/exp/slices\.CompactFunc\(\) can be replaced by slices\.CompactFunc\(\)`
63+
return true
64+
})
65+
slices.Grow(a, 2) // want `golang.org/x/exp/slices\.Grow\(\) can be replaced by slices\.Grow\(\)`
66+
slices.Clip(a) // want `golang.org/x/exp/slices\.Clip\(\) can be replaced by slices\.Clip\(\)`
67+
slices.Reverse(a) // want `golang.org/x/exp/slices\.Reverse\(\) can be replaced by slices\.Reverse\(\)`
68+
slices.Sort(a) // want `golang.org/x/exp/slices\.Sort\(\) can be replaced by slices\.Sort\(\)`
69+
slices.SortFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.SortFunc\(\) can be replaced by slices\.SortFunc\(\)`
70+
return 0
71+
})
72+
slices.SortStableFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.SortStableFunc\(\) can be replaced by slices\.SortStableFunc\(\)`
73+
return 0
74+
})
75+
slices.IsSorted(a) // want `golang.org/x/exp/slices\.IsSorted\(\) can be replaced by slices\.IsSorted\(\)`
76+
slices.IsSortedFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.IsSortedFunc\(\) can be replaced by slices\.IsSortedFunc\(\)`
77+
return 0
78+
})
79+
slices.Min(a) // want `golang.org/x/exp/slices\.Min\(\) can be replaced by slices\.Min\(\)`
80+
slices.MinFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.MinFunc\(\) can be replaced by slices\.MinFunc\(\)`
81+
return 0
82+
})
83+
slices.Max(a) // want `golang.org/x/exp/slices\.Max\(\) can be replaced by slices\.Max\(\)`
84+
slices.MaxFunc(a, func(_, _ string) int { // want `golang.org/x/exp/slices\.MaxFunc\(\) can be replaced by slices\.MaxFunc\(\)`
85+
return 0
86+
})
87+
slices.BinarySearch(a, "a") // want `golang.org/x/exp/slices\.BinarySearch\(\) can be replaced by slices\.BinarySearch\(\)`
88+
slices.BinarySearchFunc(a, b, func(_ string, _ []string) int { // want `golang.org/x/exp/slices\.BinarySearchFunc\(\) can be replaced by slices\.BinarySearchFunc\(\)`
89+
return 0
90+
})
91+
}

0 commit comments

Comments
 (0)