Skip to content

Commit 894ba0d

Browse files
committed
Resolve #146: prealloc linter support
1 parent 815d131 commit 894ba0d

File tree

13 files changed

+1038
-7
lines changed

13 files changed

+1038
-7
lines changed

Diff for: .golangci.example.yml

+11-1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,15 @@ linters-settings:
128128
nakedret:
129129
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
130130
max-func-lines: 30
131+
prealloc:
132+
# XXX: we don't recommend using this linter before doing performance profiling.
133+
# For most programs usage of prealloc will be a premature optimization.
134+
135+
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
136+
# True by default.
137+
simple: true
138+
range-loops: true # Report preallocation suggestions on range loops, true by default
139+
for-loops: false # Report preallocation suggestions on for loops, false by default
131140

132141

133142
linters:
@@ -136,7 +145,8 @@ linters:
136145
- govet
137146
enable-all: false
138147
disable:
139-
maligned
148+
- maligned
149+
- prealloc
140150
disable-all: false
141151
presets:
142152
- bugs

Diff for: .golangci.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ linters-settings:
2424
linters:
2525
enable-all: true
2626
disable:
27-
- maligned
27+
- maligned
28+
- prealloc

Diff for: Gopkg.lock

+7-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: README.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ misspell: Finds commonly misspelled English words in comments [fast: true]
127127
lll: Reports long lines [fast: true]
128128
unparam: Reports unused function parameters [fast: false]
129129
nakedret: Finds naked returns in functions greater than a specified function length [fast: true]
130+
prealloc: Finds slice declarations that could potentially be preallocated [fast: true]
130131
```
131132

132133
Pass `-E/--enable` to enable linter and `-D/--disable` to disable:
@@ -313,6 +314,7 @@ golangci-lint linters
313314
- [lll](https://github.com/walle/lll) - Reports long lines
314315
- [unparam](https://github.com/mvdan/unparam) - Reports unused function parameters
315316
- [nakedret](https://github.com/alexkohler/nakedret) - Finds naked returns in functions greater than a specified function length
317+
- [prealloc](https://github.com/alexkohler/prealloc) - Finds slice declarations that could potentially be preallocated
316318

317319
# Configuration
318320
The config file has lower priority than command-line options. If the same bool/string/int option is provided on the command-line
@@ -539,6 +541,15 @@ linters-settings:
539541
nakedret:
540542
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
541543
max-func-lines: 30
544+
prealloc:
545+
# XXX: we don't recommend using this linter before doing performance profiling.
546+
# For most programs usage of prealloc will be a premature optimization.
547+
548+
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
549+
# True by default.
550+
simple: true
551+
range-loops: true # Report preallocation suggestions on range loops, true by default
552+
for-loops: false # Report preallocation suggestions on for loops, false by default
542553

543554

544555
linters:
@@ -547,7 +558,8 @@ linters:
547558
- govet
548559
enable-all: false
549560
disable:
550-
maligned
561+
- maligned
562+
- prealloc
551563
disable-all: false
552564
presets:
553565
- bugs
@@ -620,6 +632,7 @@ linters:
620632
enable-all: true
621633
disable:
622634
- maligned
635+
- prealloc
623636
```
624637
625638
# False Positives
@@ -726,6 +739,7 @@ There is the most valuable changes log:
726739
1. Add support of the next linters:
727740
* unparam
728741
* misspell
742+
* prealloc
729743
* nakedret
730744
* lll
731745
* depguard

Diff for: README.tmpl.md

+1
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ There is the most valuable changes log:
388388
1. Add support of the next linters:
389389
* unparam
390390
* misspell
391+
* prealloc
391392
* nakedret
392393
* lll
393394
* depguard

Diff for: pkg/config/config.go

+15-3
Original file line numberDiff line numberDiff line change
@@ -163,19 +163,26 @@ type LintersSettings struct {
163163
Lll LllSettings
164164
Unparam UnparamSettings
165165
Nakedret NakedretSettings
166+
Prealloc PreallocSettings
166167
}
167168

168169
type LllSettings struct {
169170
LineLength int `mapstructure:"line-length"`
170171
}
171172

173+
type UnparamSettings struct {
174+
CheckExported bool `mapstructure:"check-exported"`
175+
Algo string
176+
}
177+
172178
type NakedretSettings struct {
173179
MaxFuncLines int `mapstructure:"max-func-lines"`
174180
}
175181

176-
type UnparamSettings struct {
177-
CheckExported bool `mapstructure:"check-exported"`
178-
Algo string
182+
type PreallocSettings struct {
183+
Simple bool
184+
RangeLoops bool `mapstructure:"range-loops"`
185+
ForLoops bool `mapstructure:"for-loops"`
179186
}
180187

181188
var defaultLintersSettings = LintersSettings{
@@ -188,6 +195,11 @@ var defaultLintersSettings = LintersSettings{
188195
Nakedret: NakedretSettings{
189196
MaxFuncLines: 30,
190197
},
198+
Prealloc: PreallocSettings{
199+
Simple: true,
200+
RangeLoops: true,
201+
ForLoops: false,
202+
},
191203
}
192204

193205
type Linters struct {

Diff for: pkg/golinters/prealloc.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package golinters
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"go/ast"
7+
8+
"github.com/golangci/golangci-lint/pkg/lint/linter"
9+
"github.com/golangci/golangci-lint/pkg/result"
10+
"github.com/golangci/prealloc"
11+
)
12+
13+
type Prealloc struct{}
14+
15+
func (Prealloc) Name() string {
16+
return "prealloc"
17+
}
18+
19+
func (Prealloc) Desc() string {
20+
return "Finds slice declarations that could potentially be preallocated"
21+
}
22+
23+
func (lint Prealloc) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Issue, error) {
24+
var res []result.Issue
25+
26+
s := &lintCtx.Settings().Prealloc
27+
for _, f := range lintCtx.ASTCache.GetAllValidFiles() {
28+
hints := prealloc.Check([]*ast.File{f.F}, s.Simple, s.RangeLoops, s.ForLoops)
29+
for _, hint := range hints {
30+
res = append(res, result.Issue{
31+
Pos: f.Fset.Position(hint.Pos),
32+
Text: fmt.Sprintf("Consider preallocating %s", formatCode(hint.DeclaredSliceName, lintCtx.Cfg)),
33+
FromLinter: lint.Name(),
34+
})
35+
}
36+
}
37+
38+
return res, nil
39+
}

Diff for: pkg/lint/lintersdb/lintersdb.go

+5
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ func GetAllSupportedLinterConfigs() []linter.Config {
181181
WithPresets(linter.PresetComplexity).
182182
WithSpeed(10).
183183
WithURL("https://github.com/alexkohler/nakedret"),
184+
linter.NewConfig(golinters.Prealloc{}).
185+
WithPresets(linter.PresetPerformance).
186+
WithSpeed(8).
187+
WithURL("https://github.com/alexkohler/prealloc"),
184188
}
185189

186190
if os.Getenv("GOLANGCI_COM_RUN") == "1" {
@@ -193,6 +197,7 @@ func GetAllSupportedLinterConfigs() []linter.Config {
193197
golinters.Lll{}.Name(): true, // annoying
194198
golinters.Unparam{}.Name(): true, // need to check it first
195199
golinters.Nakedret{}.Name(): true, // annoying
200+
golinters.Prealloc{}.Name(): true, // annoying
196201
}
197202
return enableLinterConfigs(lcs, func(lc *linter.Config) bool {
198203
return !disabled[lc.Linter.Name()]

Diff for: test/testdata/prealloc.go

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// args: -Eprealloc
2+
package testdata
3+
4+
func Prealloc(source []int) []int {
5+
var dest []int // ERROR "Consider preallocating `dest`"
6+
for _, v := range source {
7+
dest = append(dest, v)
8+
}
9+
10+
return dest
11+
}

Diff for: vendor/github.com/golangci/prealloc/LICENSE

+21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)