diff --git a/.golangci.reference.yml b/.golangci.reference.yml index 2ceb0889283b..5170276f374d 100644 --- a/.golangci.reference.yml +++ b/.golangci.reference.yml @@ -2301,6 +2301,7 @@ linters: - nosnakecase - nosprintfhostport - paralleltest + - perfsprint - prealloc - predeclared - promlinter @@ -2420,6 +2421,7 @@ linters: - nosnakecase - nosprintfhostport - paralleltest + - perfsprint - prealloc - predeclared - promlinter diff --git a/go.mod b/go.mod index f1c75aac665b..91c73e44a227 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,7 @@ require ( github.com/breml/errchkjson v0.3.6 github.com/butuzov/ireturn v0.2.1 github.com/butuzov/mirror v1.1.0 + github.com/catenacyber/perfsprint v0.2.0 github.com/charithe/durationcheck v0.0.10 github.com/curioswitch/go-reassign v0.2.0 github.com/daixiang0/gci v0.11.2 diff --git a/go.sum b/go.sum index 6d3d95feea71..5392e7ff789c 100644 --- a/go.sum +++ b/go.sum @@ -102,6 +102,8 @@ github.com/butuzov/ireturn v0.2.1 h1:w5Ks4tnfeFDZskGJ2x1GAkx5gaQV+kdU3NKNr3NEBzY github.com/butuzov/ireturn v0.2.1/go.mod h1:RfGHUvvAuFFxoHKf4Z8Yxuh6OjlCw1KvR2zM1NFHeBk= github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI= github.com/butuzov/mirror v1.1.0/go.mod h1:8Q0BdQU6rC6WILDiBM60DBfvV78OLJmMmixe7GF45AE= +github.com/catenacyber/perfsprint v0.2.0 h1:azOocHLscPjqXVJ7Mf14Zjlkn4uNua0+Hcg1wTR6vUo= +github.com/catenacyber/perfsprint v0.2.0/go.mod h1:/wclWYompEyjUD2FuIIDVKNkqz7IgBIWXIH3V0Zol50= github.com/ccojocar/zxcvbn-go v1.0.1 h1:+sxrANSCj6CdadkcMnvde/GWU1vZiiXRbqYSCalV4/4= github.com/ccojocar/zxcvbn-go v1.0.1/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= diff --git a/pkg/golinters/perfsprint.go b/pkg/golinters/perfsprint.go new file mode 100644 index 000000000000..fb248a85dcdf --- /dev/null +++ b/pkg/golinters/perfsprint.go @@ -0,0 +1,19 @@ +package golinters + +import ( + "github.com/catenacyber/perfsprint/analyzer" + "golang.org/x/tools/go/analysis" + + "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" +) + +func NewPerfSprint() *goanalysis.Linter { + a := analyzer.Analyzer + + return goanalysis.NewLinter( + a.Name, + a.Doc, + []*analysis.Analyzer{a}, + nil, + ).WithLoadMode(goanalysis.LoadModeTypesInfo) +} diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index f725de95fa21..fd329ce57fcf 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -712,6 +712,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithPresets(linter.PresetStyle, linter.PresetTest). WithURL("https://github.com/kunwardeep/paralleltest"), + linter.NewConfig(golinters.NewPerfSprint()). + WithSince("v1.55.0"). + WithLoadForGoAnalysis(). + WithPresets(linter.PresetPerformance). + WithURL("https://github.com/catenacyber/perfsprint"), + linter.NewConfig(golinters.NewPreAlloc(preallocCfg)). WithSince("v1.19.0"). WithPresets(linter.PresetPerformance). diff --git a/test/testdata/perfsprint.go b/test/testdata/perfsprint.go new file mode 100644 index 000000000000..77956385f187 --- /dev/null +++ b/test/testdata/perfsprint.go @@ -0,0 +1,49 @@ +//golangcitest:args -Eperfsprint +package testdata + +import "fmt" + +func TestPerfsprint() { + var ( + s string + err error + b bool + i int + i64 int64 + ui uint + ) + + fmt.Sprintf("%s", s) // want "fmt.Sprintf can be replaced with just using the string" + fmt.Sprint(s) // want "fmt.Sprint can be replaced with just using the string" + fmt.Sprintf("%s", err) // want "fmt.Sprintf can be replaced with err.Error()" + fmt.Sprint(err) // want "fmt.Sprint can be replaced with err.Error()" + fmt.Sprintf("%t", b) // want "fmt.Sprintf can be replaced with faster strconv.FormatBool" + fmt.Sprint(b) // want "fmt.Sprint can be replaced with faster strconv.FormatBool" + fmt.Sprintf("%d", i) // want "fmt.Sprintf can be replaced with faster strconv.Itoa" + fmt.Sprint(i) // want "fmt.Sprint can be replaced with faster strconv.Itoa" + fmt.Sprintf("%d", i64) // want "fmt.Sprintf can be replaced with faster strconv.FormatInt" + fmt.Sprint(i64) // want "fmt.Sprint can be replaced with faster strconv.FormatInt" + fmt.Sprintf("%d", ui) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint" + fmt.Sprint(ui) // want "fmt.Sprint can be replaced with faster strconv.FormatUint" + fmt.Sprintf("%x", []byte{'a'}) // want "fmt.Sprintf can be replaced with faster hex.EncodeToString" + + fmt.Sprint("test", 42) + fmt.Sprint(42, 42) + fmt.Sprintf("test") + fmt.Sprintf("%v") + fmt.Sprintf("%d") + fmt.Sprintf("%d", 42, 42) + fmt.Sprintf("%#d", 42) + fmt.Sprintf("value %d", 42) + fmt.Sprintf("val%d", 42) + fmt.Sprintf("%s %v", "hello", "world") + fmt.Sprintf("%#v", 42) + fmt.Sprintf("%T", struct{ string }{}) + fmt.Sprintf("%%v", 42) + fmt.Sprintf("%3d", 42) + fmt.Sprintf("% d", 42) + fmt.Sprintf("%-10d", 42) + fmt.Sprintf("%[2]d %[1]d\n", 11, 22) + fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6) + fmt.Sprintf("%d %d %#[1]x %#x", 16, 17) +}