Skip to content

Commit

Permalink
gocritic: support autofix (#2450)
Browse files Browse the repository at this point in the history
  • Loading branch information
peakle committed Jan 3, 2022
1 parent 891b9da commit 3d17f2f
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 3 deletions.
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 16 additions & 3 deletions pkg/golinters/gocritic.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down Expand Up @@ -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)
}
}

Expand Down
14 changes: 14 additions & 0 deletions test/ruleguard/rangeExprCopy.go
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions test/testdata/fix/in/gocritic.go
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions test/testdata/fix/out/gocritic.go
Original file line number Diff line number Diff line change
@@ -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")
}
}

0 comments on commit 3d17f2f

Please sign in to comment.