mirror: linter that suggest using alternative string/[]byte functions (#3825)
Some checks failed
Release a tag / release (push) Has been cancelled
Release a tag / docker-release (map[Dockerfile:build/Dockerfile]) (push) Has been cancelled
Release a tag / docker-release (map[Dockerfile:build/alpine.Dockerfile]) (push) Has been cancelled

This commit is contained in:
Oleg Butuzov 2023-06-01 15:16:39 +03:00 committed by GitHub
parent 13de2502b0
commit 9f2528a30c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 93 additions and 0 deletions

View File

@ -2140,6 +2140,7 @@ linters:
- maintidx - maintidx
- makezero - makezero
- maligned - maligned
- mirror
- misspell - misspell
- musttag - musttag
- nakedret - nakedret
@ -2253,6 +2254,7 @@ linters:
- maintidx - maintidx
- makezero - makezero
- maligned - maligned
- mirror
- misspell - misspell
- musttag - musttag
- nakedret - nakedret

1
go.mod
View File

@ -24,6 +24,7 @@ require (
github.com/breml/bidichk v0.2.4 github.com/breml/bidichk v0.2.4
github.com/breml/errchkjson v0.3.1 github.com/breml/errchkjson v0.3.1
github.com/butuzov/ireturn v0.2.0 github.com/butuzov/ireturn v0.2.0
github.com/butuzov/mirror v1.1.0
github.com/charithe/durationcheck v0.0.10 github.com/charithe/durationcheck v0.0.10
github.com/curioswitch/go-reassign v0.2.0 github.com/curioswitch/go-reassign v0.2.0
github.com/daixiang0/gci v0.10.1 github.com/daixiang0/gci v0.10.1

2
go.sum generated
View File

@ -94,6 +94,8 @@ github.com/breml/errchkjson v0.3.1 h1:hlIeXuspTyt8Y/UmP5qy1JocGNR00KQHgfaNtRAjox
github.com/breml/errchkjson v0.3.1/go.mod h1:XroxrzKjdiutFyW3nWhw34VGg7kiMsDQox73yWCGI2U= github.com/breml/errchkjson v0.3.1/go.mod h1:XroxrzKjdiutFyW3nWhw34VGg7kiMsDQox73yWCGI2U=
github.com/butuzov/ireturn v0.2.0 h1:kCHi+YzC150GE98WFuZQu9yrTn6GEydO2AuPLbTgnO4= github.com/butuzov/ireturn v0.2.0 h1:kCHi+YzC150GE98WFuZQu9yrTn6GEydO2AuPLbTgnO4=
github.com/butuzov/ireturn v0.2.0/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= github.com/butuzov/ireturn v0.2.0/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc=
github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI=
github.com/butuzov/mirror v1.1.0/go.mod h1:8Q0BdQU6rC6WILDiBM60DBfvV78OLJmMmixe7GF45AE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=

70
pkg/golinters/mirror.go Normal file
View File

@ -0,0 +1,70 @@
package golinters
import (
"sync"
"github.com/butuzov/mirror"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
"github.com/golangci/golangci-lint/pkg/lint/linter"
"github.com/golangci/golangci-lint/pkg/result"
)
func NewMirror() *goanalysis.Linter {
var (
mu sync.Mutex
issues []goanalysis.Issue
)
a := mirror.NewAnalyzer()
a.Run = func(pass *analysis.Pass) (any, error) {
// mirror only lints test files if the `--with-tests` flag is passed,
// so we pass the `with-tests` flag as true to the analyzer before running it.
// This can be turned off by using the regular golangci-lint flags such as `--tests` or `--skip-files`
// or can be disabled per linter via exclude rules.
// (see https://github.com/golangci/golangci-lint/issues/2527#issuecomment-1023707262)
violations := mirror.Run(pass, true)
if len(violations) == 0 {
return nil, nil
}
for index := range violations {
i := violations[index].Issue(pass.Fset)
issue := result.Issue{
FromLinter: a.Name,
Text: i.Message,
Pos: i.Start,
}
if len(i.InlineFix) > 0 {
issue.Replacement = &result.Replacement{
Inline: &result.InlineFix{
StartCol: i.Start.Column - 1,
Length: len(i.Original),
NewString: i.InlineFix,
},
}
}
mu.Lock()
issues = append(issues, goanalysis.NewIssue(&issue, pass))
mu.Unlock()
}
return nil, nil
}
analyzer := goanalysis.NewLinter(
a.Name,
a.Doc,
[]*analysis.Analyzer{a},
nil,
).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
return issues
}).WithLoadMode(goanalysis.LoadModeTypesInfo)
return analyzer
}

View File

@ -654,6 +654,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithURL("https://github.com/mdempsky/maligned"). WithURL("https://github.com/mdempsky/maligned").
Deprecated("The repository of the linter has been archived by the owner.", "v1.38.0", "govet 'fieldalignment'"), Deprecated("The repository of the linter has been archived by the owner.", "v1.38.0", "govet 'fieldalignment'"),
linter.NewConfig(golinters.NewMirror()).
WithSince("v1.53.0").
WithPresets(linter.PresetStyle).
WithLoadForGoAnalysis().
WithURL("https://github.com/butuzov/mirror"),
linter.NewConfig(golinters.NewMisspell(misspellCfg)). linter.NewConfig(golinters.NewMisspell(misspellCfg)).
WithSince("v1.8.0"). WithSince("v1.8.0").
WithPresets(linter.PresetStyle, linter.PresetComment). WithPresets(linter.PresetStyle, linter.PresetComment).

12
test/testdata/mirror.go vendored Normal file
View File

@ -0,0 +1,12 @@
//golangcitest:args -Emirror
package testdata
import (
"strings"
"unicode/utf8"
)
func foobar() {
_ = utf8.RuneCount([]byte("foobar")) // want `avoid allocations with utf8\.RuneCountInString`
_ = strings.Compare(string([]byte{'f', 'o', 'o', 'b', 'a', 'r'}), string([]byte{'f', 'o', 'o', 'b', 'a', 'r'})) // want `avoid allocations with bytes\.Compare`
}