From ba81211e5f78d09c8ab1cfcb15555c991a2c4a49 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Mon, 9 Oct 2023 21:24:32 +0200 Subject: [PATCH 1/5] linter: add perfsprint --- .golangci.reference.yml | 2 ++ go.mod | 1 + go.sum | 2 ++ pkg/golinters/perfsprint.go | 17 +++++++++++++++++ pkg/lint/lintersdb/manager.go | 5 +++++ test/testdata/perfsprint.go | 8 ++++++++ 6 files changed, 35 insertions(+) create mode 100644 pkg/golinters/perfsprint.go create mode 100644 test/testdata/perfsprint.go 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..b16916cbd40a --- /dev/null +++ b/pkg/golinters/perfsprint.go @@ -0,0 +1,17 @@ +package golinters + +import ( + "github.com/catenacyber/perfsprint/analyzer" + "golang.org/x/tools/go/analysis" + + "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" +) + +func NewGoStrconv() *goanalysis.Linter { + return goanalysis.NewLinter( + "perfsprint", + "Checks usages of `fmt.Sprintf` which have faster alternatives.", + []*analysis.Analyzer{analyzer.Analyzer}, + nil, + ).WithLoadMode(goanalysis.LoadModeSyntax) +} diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index f725de95fa21..f51f8e123ebd 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -712,6 +712,11 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithPresets(linter.PresetStyle, linter.PresetTest). WithURL("https://github.com/kunwardeep/paralleltest"), + linter.NewConfig(golinters.NewPerfSprint()). + WithSince("v1.54.2"). + WithPresets(linter.PresetStyle). + 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..2a272654cb59 --- /dev/null +++ b/test/testdata/perfsprint.go @@ -0,0 +1,8 @@ +//golangcitest:args -Eperfsprint +package testdata + +import "fmt" + +func SprintfCouldBeStrconv() { + fmt.Sprintf("%d", 42) // want "Sprintf can be replaced with faster strconv.Itoa" +} From 71df6c3f3f10f9ca4d89fedf5a89de565457cfca Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 19 Oct 2023 22:29:34 +0200 Subject: [PATCH 2/5] fixup! linter: add perfsprint --- pkg/golinters/perfsprint.go | 2 +- pkg/lint/lintersdb/manager.go | 2 +- test/testdata/perfsprint.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/golinters/perfsprint.go b/pkg/golinters/perfsprint.go index b16916cbd40a..681629284d20 100644 --- a/pkg/golinters/perfsprint.go +++ b/pkg/golinters/perfsprint.go @@ -7,7 +7,7 @@ import ( "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" ) -func NewGoStrconv() *goanalysis.Linter { +func NewPerfSprint() *goanalysis.Linter { return goanalysis.NewLinter( "perfsprint", "Checks usages of `fmt.Sprintf` which have faster alternatives.", diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index f51f8e123ebd..a46174fee719 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -714,7 +714,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { linter.NewConfig(golinters.NewPerfSprint()). WithSince("v1.54.2"). - WithPresets(linter.PresetStyle). + WithPresets(linter.PresetPerformance). WithURL("https://github.com/catenacyber/perfsprint"), linter.NewConfig(golinters.NewPreAlloc(preallocCfg)). diff --git a/test/testdata/perfsprint.go b/test/testdata/perfsprint.go index 2a272654cb59..284ad2ea1d4c 100644 --- a/test/testdata/perfsprint.go +++ b/test/testdata/perfsprint.go @@ -4,5 +4,5 @@ package testdata import "fmt" func SprintfCouldBeStrconv() { - fmt.Sprintf("%d", 42) // want "Sprintf can be replaced with faster strconv.Itoa" + fmt.Sprintf("%d", 42) // want "fmt.Sprintf can be replaced with faster function strconv.Itoa" } From ac01747804f7ed7e0a19225c50323c311295921c Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Thu, 19 Oct 2023 22:35:38 +0200 Subject: [PATCH 3/5] review: fix --- pkg/golinters/perfsprint.go | 10 ++++++---- pkg/lint/lintersdb/manager.go | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pkg/golinters/perfsprint.go b/pkg/golinters/perfsprint.go index 681629284d20..fb248a85dcdf 100644 --- a/pkg/golinters/perfsprint.go +++ b/pkg/golinters/perfsprint.go @@ -8,10 +8,12 @@ import ( ) func NewPerfSprint() *goanalysis.Linter { + a := analyzer.Analyzer + return goanalysis.NewLinter( - "perfsprint", - "Checks usages of `fmt.Sprintf` which have faster alternatives.", - []*analysis.Analyzer{analyzer.Analyzer}, + a.Name, + a.Doc, + []*analysis.Analyzer{a}, nil, - ).WithLoadMode(goanalysis.LoadModeSyntax) + ).WithLoadMode(goanalysis.LoadModeTypesInfo) } diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index a46174fee719..fd329ce57fcf 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -713,7 +713,8 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithURL("https://github.com/kunwardeep/paralleltest"), linter.NewConfig(golinters.NewPerfSprint()). - WithSince("v1.54.2"). + WithSince("v1.55.0"). + WithLoadForGoAnalysis(). WithPresets(linter.PresetPerformance). WithURL("https://github.com/catenacyber/perfsprint"), From 1219bec5279c4e63aecd6045ab4b8b899daa9f27 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 19 Oct 2023 22:40:26 +0200 Subject: [PATCH 4/5] fixup! review: fix --- test/testdata/perfsprint.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testdata/perfsprint.go b/test/testdata/perfsprint.go index 284ad2ea1d4c..89067d0a13a6 100644 --- a/test/testdata/perfsprint.go +++ b/test/testdata/perfsprint.go @@ -4,5 +4,5 @@ package testdata import "fmt" func SprintfCouldBeStrconv() { - fmt.Sprintf("%d", 42) // want "fmt.Sprintf can be replaced with faster function strconv.Itoa" + fmt.Sprintf("%d", 42) // want "fmt.Sprintf can be replaced with faster strconv.Itoa" } From b11b7a6586e297d240f11cb65e18d91f740ca7fb Mon Sep 17 00:00:00 2001 From: Anton Telyshev Date: Fri, 20 Oct 2023 09:55:39 +0300 Subject: [PATCH 5/5] review: add basic positive and negative cases --- test/testdata/perfsprint.go | 45 +++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/test/testdata/perfsprint.go b/test/testdata/perfsprint.go index 89067d0a13a6..77956385f187 100644 --- a/test/testdata/perfsprint.go +++ b/test/testdata/perfsprint.go @@ -3,6 +3,47 @@ package testdata import "fmt" -func SprintfCouldBeStrconv() { - fmt.Sprintf("%d", 42) // want "fmt.Sprintf can be replaced with faster strconv.Itoa" +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) }