Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

checkers: add new checker stringsCompare #1195

Merged
merged 12 commits into from Feb 5, 2022
31 changes: 31 additions & 0 deletions checkers/rules/rules.go
Expand Up @@ -736,3 +736,34 @@ func dynamicFmtString(m dsl.Matcher) {
Suggest("errors.New($f($*args))").
Report(`use errors.New($f($*args)) or fmt.Errorf("%s", $f($*args)) instead`)
}

//doc:summary Detects strings.Compare usage
//doc:tags performance experimental
quasilyte marked this conversation as resolved.
Show resolved Hide resolved
//doc:before strings.Compare(x, y)
//doc:after x < y
func stringsCompare(m dsl.Matcher) {
m.Match(`strings.Compare($s1, $s2) == 0`).
Report(`don't use strings.Compare on hot path, change it to built-in operators`).
quasilyte marked this conversation as resolved.
Show resolved Hide resolved
Suggest(`$s1 == $s2`).
At(m["s1"])

m.Match(`strings.Compare($s1, $s2) < 0`,
`strings.Compare($s1, $s2) == -1`).
Report(`don't use strings.Compare on hot path, change it to built-in operators`).
Suggest(`$s1 < $s2`).
At(m["s1"])

m.Match(`strings.Compare($s1, $s2) > 0`,
`strings.Compare($s1, $s2) == 1`).
Report(`don't use strings.Compare on hot path, change it to built-in operators`).
Suggest(`$s1 > $s2`).
At(m["s1"])

m.Match(`$_ = strings.Compare($s1, $_)`,
quasilyte marked this conversation as resolved.
Show resolved Hide resolved
`$_ := strings.Compare($s1, $_)`,
`var $_ = strings.Compare($s1, $_)`,
`var $_ $_ = strings.Compare($s1, $_)`,
`switch strings.Compare($s1, $_) { $*_ }`).
Report(`don't use strings.Compare on hot path, change it to built-in operators`).
At(m["s1"])
}
55 changes: 55 additions & 0 deletions checkers/rulesdata/rulesdata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions checkers/testdata/stringsCompare/negative_tests.go
@@ -0,0 +1,21 @@
package checker_test

import (
"bytes"
)

type s []string

func (s) Compare(x, y string) int {
if x < y {
return 1
}
return 0
}

func negative() {
bytes.Compare([]byte{}, []byte{})

strings := s{}
_ = strings.Compare("1", "3") == 0
}
36 changes: 36 additions & 0 deletions checkers/testdata/stringsCompare/positive_tests.go
@@ -0,0 +1,36 @@
package checker_test

import (
"strings"
)

func foo() {
f, b := "aaa", "bbb"

/*! don't use strings.Compare on hot path, change it to built-in operators */
if strings.Compare(f, b) == 0 {
}

/*! don't use strings.Compare on hot path, change it to built-in operators */
switch strings.Compare(f, b) {
case 0:
print(0)
case 1:
print(1)
case -1:
print(-1)
}

/*! don't use strings.Compare on hot path, change it to built-in operators */
switch dd := strings.Compare(f, b); dd {
case 0:
print(0)
case 1:
print(1)
case -1:
print(-1)
}

/*! don't use strings.Compare on hot path, change it to built-in operators */
_ = strings.Compare("s", "ww")
}