gocritic: support autofix (#2450)

This commit is contained in:
Denis Limarev 2022-01-04 00:57:05 +03:00 committed by GitHub
parent 891b9dae54
commit 3d17f2fac1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 3 deletions

View File

@ -29,6 +29,12 @@ test: build
GL_TEST_RUN=1 go test -v -parallel 2 ./...
.PHONY: test
# ex: T=gofmt.go make test_fix
# the value of `T` is the name of a file from `test/testdata/fix`
test_fix: build
GL_TEST_RUN=1 go test -v ./test -count 1 -run TestFix/$T
.PHONY: test_fix
test_race: build_race
GL_TEST_RUN=1 ./golangci-lint run -v --timeout=5m
.PHONY: test_race

View File

@ -48,8 +48,9 @@ Dynamic rules are written declaratively with AST patterns, filters, report messa
}
linterCtx.SetPackageInfo(pass.TypesInfo, pass.Pkg)
var res []goanalysis.Issue
pkgIssues := runGocriticOnPackage(linterCtx, enabledCheckers, pass.Files)
res := make([]goanalysis.Issue, 0, len(pkgIssues))
for i := range pkgIssues {
res = append(res, goanalysis.NewIssue(&pkgIssues[i], pass))
}
@ -179,11 +180,23 @@ func runGocriticOnFile(ctx *gocriticlinter.Context, f *ast.File, checkers []*goc
// as read-only structure, so no copying is required.
for _, warn := range c.Check(f) {
pos := ctx.FileSet.Position(warn.Node.Pos())
res = append(res, result.Issue{
issue := result.Issue{
Pos: pos,
Text: fmt.Sprintf("%s: %s", c.Info.Name, warn.Text),
FromLinter: gocriticName,
})
}
if warn.HasQuickFix() {
issue.Replacement = &result.Replacement{
Inline: &result.InlineFix{
StartCol: pos.Column - 1,
Length: int(warn.Node.End() - warn.Node.Pos()),
NewString: string(warn.Suggestion.Replacement),
},
}
}
res = append(res, issue)
}
}

View File

@ -0,0 +1,14 @@
// go:build ruleguard
package ruleguard
import (
"github.com/quasilyte/go-ruleguard/dsl"
)
func RangeExprVal(m dsl.Matcher) {
m.Match(`for _, $_ := range $x { $*_ }`, `for _, $_ = range $x { $*_ }`).
Where(m["x"].Addressable && m["x"].Type.Size >= 512).
Report(`$x copy can be avoided with &$x`).
At(m["x"]).
Suggest(`&$x`)
}

22
test/testdata/fix/in/gocritic.go vendored Normal file
View File

@ -0,0 +1,22 @@
//args: -Egocritic
//config: linters-settings.gocritic.enabled-checks=ruleguard
//config: linters-settings.gocritic.settings.ruleguard.rules=ruleguard/rangeExprCopy.go,ruleguard/strings_simplify.go
package p
import (
"strings"
)
func gocritic() {
var xs [2048]byte
// xs -> &xs
for _, x := range xs {
print(x)
}
// strings.Count("foo", "bar") == 0 -> !strings.Contains("foo", "bar")
if strings.Count("foo", "bar") == 0 {
print("qu")
}
}

22
test/testdata/fix/out/gocritic.go vendored Normal file
View File

@ -0,0 +1,22 @@
//args: -Egocritic
//config: linters-settings.gocritic.enabled-checks=ruleguard
//config: linters-settings.gocritic.settings.ruleguard.rules=ruleguard/rangeExprCopy.go,ruleguard/strings_simplify.go
package p
import (
"strings"
)
func gocritic() {
var xs [2048]byte
// xs -> &xs
for _, x := range &xs {
print(x)
}
// strings.Count("foo", "bar") == 0 -> !strings.Contains("foo", "bar")
if !strings.Contains("foo", "bar") {
print("qu")
}
}