From 1d7b6c3c2003faa283346cb92535f15301a62795 Mon Sep 17 00:00:00 2001 From: Kamil Samigullin Date: Thu, 15 Apr 2021 14:17:14 +0300 Subject: [PATCH] fix #1404: integrate looppointer --- go.mod | 1 + go.sum | 5 +++++ pkg/golinters/looppointer.go | 21 +++++++++++++++++++++ pkg/lint/lintersdb/manager.go | 4 ++++ test/testdata/looppointer.go | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+) create mode 100644 pkg/golinters/looppointer.go create mode 100644 test/testdata/looppointer.go diff --git a/go.mod b/go.mod index e4df46a8b36a..4f922d58b7b6 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( github.com/kulti/thelper v0.4.0 github.com/kunwardeep/paralleltest v1.0.2 github.com/kyoh86/exportloopref v0.1.8 + github.com/kyoh86/looppointer v0.1.7 github.com/ldez/gomoddirectives v0.2.1 github.com/ldez/tagliatelle v0.2.0 github.com/maratori/testpackage v1.0.1 diff --git a/go.sum b/go.sum index da58aed60eda..23586e1185e5 100644 --- a/go.sum +++ b/go.sum @@ -378,6 +378,10 @@ github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2G github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/kyoh86/looppointer v0.1.7 h1:q5sZOhFvmvQ6ZoZxvPB/Mjj2croWX7L49BBuI4XQWCM= +github.com/kyoh86/looppointer v0.1.7/go.mod h1:l0cRF49N6xDPx8IuBGC/imZo8Yn1BBLJY0vzI+4fepc= +github.com/kyoh86/nolint v0.0.0-20200711045849-7a7b0d649b7a h1:WKwgzTn8xp2JuhOUsTbi+h+QygLZSfVGwaYZUejGMMw= +github.com/kyoh86/nolint v0.0.0-20200711045849-7a7b0d649b7a/go.mod h1:hPeUNhNOZ22wXzQKMzeYKXVFTBjJ9czxjeIDyI1ueVM= github.com/ldez/gomoddirectives v0.2.1 h1:9pAcW9KRZW7HQjFwbozNvFMcNVwdCBufU7os5QUwLIY= github.com/ldez/gomoddirectives v0.2.1/go.mod h1:sGicqkRgBOg//JfpXwkB9Hj0X5RyJ7mlACM5B9f6Me4= github.com/ldez/tagliatelle v0.2.0 h1:693V8Bf1NdShJ8eu/s84QySA0J2VWBanVBa2WwXD/Wk= @@ -904,6 +908,7 @@ golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200710042808-f1c4188a97a1/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= diff --git a/pkg/golinters/looppointer.go b/pkg/golinters/looppointer.go new file mode 100644 index 000000000000..b52326d9f335 --- /dev/null +++ b/pkg/golinters/looppointer.go @@ -0,0 +1,21 @@ +package golinters + +import ( + "github.com/kyoh86/looppointer" + "golang.org/x/tools/go/analysis" + + "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" +) + +// NewLoopPointer returns a new instance of Linter based on +// github.com/kyoh86/looppointer. +func NewLoopPointer() *goanalysis.Linter { + analyzer := looppointer.Analyzer + + return goanalysis.NewLinter( + analyzer.Name, + analyzer.Doc, + []*analysis.Analyzer{analyzer}, + nil, + ).WithLoadMode(goanalysis.LoadModeTypesInfo) +} diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index 0b8eda617d1b..373c80e9b08c 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -488,6 +488,10 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithSince("v1.40.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/ldez/tagliatelle"), + linter.NewConfig(golinters.NewLoopPointer()). + WithSince("v1.40.0"). + WithPresets(linter.PresetBugs). + WithURL("https://github.com/kyoh86/looppointer"), // nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives linter.NewConfig(golinters.NewNoLintLint()). diff --git a/test/testdata/looppointer.go b/test/testdata/looppointer.go new file mode 100644 index 000000000000..d7cb5de86471 --- /dev/null +++ b/test/testdata/looppointer.go @@ -0,0 +1,34 @@ +//args: -Elooppointer +package testdata + +func lintLoopPointer() { + type domain struct { + property *int + } + + type dto struct { + prop int + cond bool + } + + result := make([]domain, 0, 3) + for _, d := range []dto{ + {prop: 10}, + {prop: 11}, + {prop: 12}, + } { + p := domain{} + if !d.cond { + p.property = &d.prop // ERROR "taking a pointer for the loop variable d" + } + result = append(result, p) + } + + for _, r := range result { + if r.property != nil { + // expected 10, 11, 12 + // obtained 12, 12, 12 + println(*r.property) + } + } +}