Skip to content

Commit 0842afe

Browse files
committed
self-review fixes
1 parent 424b611 commit 0842afe

File tree

4 files changed

+85
-59
lines changed

4 files changed

+85
-59
lines changed

pkg/golinters/gocritic.go

Lines changed: 60 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ var (
3232
isGoCriticDebug = logutils.HaveDebugTag(logutils.DebugKeyGoCritic)
3333
)
3434

35-
func NewGoCritic(settings *config.GoCriticSettings, lintConfigDir string) *goanalysis.Linter {
35+
func NewGoCritic(settings *config.GoCriticSettings, lintConfigDirGetter func() string) *goanalysis.Linter {
3636
var mu sync.Mutex
3737
var resIssues []goanalysis.Issue
3838

3939
wrapper := &goCriticWrapper{
40-
lintConfigDir: lintConfigDir,
41-
sizes: types.SizesFor("gc", runtime.GOARCH),
40+
lintConfigDirGetter: lintConfigDirGetter,
41+
sizes: types.SizesFor("gc", runtime.GOARCH),
4242
}
4343

4444
analyzer := &analysis.Analyzer{
@@ -80,10 +80,10 @@ Dynamic rules are written declaratively with AST patterns, filters, report messa
8080
}
8181

8282
type goCriticWrapper struct {
83-
settingsWrapper *goCriticSettingsWrapper
84-
lintConfigDir string
85-
sizes types.Sizes
86-
once sync.Once
83+
settingsWrapper *goCriticSettingsWrapper
84+
lintConfigDirGetter func() string
85+
sizes types.Sizes
86+
once sync.Once
8787
}
8888

8989
func (w *goCriticWrapper) init(settings *config.GoCriticSettings, logger logutils.Log) {
@@ -136,15 +136,15 @@ func (w *goCriticWrapper) run(pass *analysis.Pass) ([]goanalysis.Issue, error) {
136136
}
137137

138138
func (w *goCriticWrapper) buildEnabledCheckers(linterCtx *gocriticlinter.Context) ([]*gocriticlinter.Checker, error) {
139-
allParams := w.settingsWrapper.GetLowerCasedParams()
139+
allLowerCasedParams := w.settingsWrapper.GetLowerCasedParams()
140140

141141
var enabledCheckers []*gocriticlinter.Checker
142142
for _, info := range gocriticlinter.GetCheckersInfo() {
143143
if !w.settingsWrapper.IsCheckEnabled(info.Name) {
144144
continue
145145
}
146146

147-
if err := w.configureCheckerInfo(info, allParams); err != nil {
147+
if err := w.configureCheckerInfo(info, allLowerCasedParams); err != nil {
148148
return nil, err
149149
}
150150

@@ -205,13 +205,17 @@ func runGocriticOnFile(linterCtx *gocriticlinter.Context, f *ast.File, checks []
205205
return res
206206
}
207207

208-
func (w *goCriticWrapper) configureCheckerInfo(info *gocriticlinter.CheckerInfo, allParams map[string]config.GoCriticCheckSettings) error {
209-
params := allParams[strings.ToLower(info.Name)]
208+
func (w *goCriticWrapper) configureCheckerInfo(
209+
info *gocriticlinter.CheckerInfo,
210+
allLowerCasedParams map[string]config.GoCriticCheckSettings,
211+
) error {
212+
params := allLowerCasedParams[strings.ToLower(info.Name)]
210213
if params == nil { // no config for this checker
211214
return nil
212215
}
213216

214-
infoParams := normalizeCheckerInfoParams(info)
217+
// NOTE(ldez): lowercase info param keys here because golangci-lint's config parser lowercases all strings.
218+
infoParams := normalizeMap(info.Params)
215219
for k, p := range params {
216220
v, ok := infoParams[k]
217221
if ok {
@@ -235,13 +239,11 @@ func (w *goCriticWrapper) configureCheckerInfo(info *gocriticlinter.CheckerInfo,
235239
return nil
236240
}
237241

238-
func normalizeCheckerInfoParams(info *gocriticlinter.CheckerInfo) gocriticlinter.CheckerParams {
239-
// lowercase info param keys here because golangci-lint's config parser lowercases all strings
240-
ret := gocriticlinter.CheckerParams{}
241-
for k, v := range info.Params {
242+
func normalizeMap[ValueT any](in map[string]ValueT) map[string]ValueT {
243+
ret := make(map[string]ValueT, len(in))
244+
for k, v := range in {
242245
ret[strings.ToLower(k)] = v
243246
}
244-
245247
return ret
246248
}
247249

@@ -259,7 +261,7 @@ func (w *goCriticWrapper) normalizeCheckerParamsValue(p any) any {
259261
return rv.Bool()
260262
case reflect.String:
261263
// Perform variable substitution.
262-
return strings.ReplaceAll(rv.String(), "${configDir}", w.lintConfigDir)
264+
return strings.ReplaceAll(rv.String(), "${configDir}", w.lintConfigDirGetter())
263265
default:
264266
return p
265267
}
@@ -270,54 +272,50 @@ type goCriticSettingsWrapper struct {
270272

271273
logger logutils.Log
272274

273-
allCheckers []*gocriticlinter.CheckerInfo
274-
allCheckersByName map[string]*gocriticlinter.CheckerInfo
275+
allCheckers []*gocriticlinter.CheckerInfo
275276

276-
allTagsSorted []string
277-
allChecksByTag map[string][]string
277+
allChecks map[string]struct{}
278+
allChecksLowerCased map[string]struct{}
279+
allChecksByTag map[string][]string
280+
allTagsSorted []string
278281

279-
inferredEnabledChecks map[string]struct{}
282+
inferredEnabledChecks map[string]struct{}
283+
inferredEnabledLowerCasedChecks map[string]struct{}
280284
}
281285

282286
func newGoCriticSettingsWrapper(settings *config.GoCriticSettings, logger logutils.Log) *goCriticSettingsWrapper {
283287
allCheckers := gocriticlinter.GetCheckersInfo()
284-
allCheckersByName := make(map[string]*gocriticlinter.CheckerInfo, len(allCheckers))
285-
for _, checkInfo := range allCheckers {
286-
allCheckersByName[checkInfo.Name] = checkInfo
287-
}
288288

289+
allChecks := make(map[string]struct{}, len(allCheckers))
290+
allChecksLowerCased := make(map[string]struct{}, len(allCheckers))
289291
allChecksByTag := make(map[string][]string)
290292
for _, checker := range allCheckers {
293+
allChecks[checker.Name] = struct{}{}
294+
allChecksLowerCased[strings.ToLower(checker.Name)] = struct{}{}
295+
291296
for _, tag := range checker.Tags {
292297
allChecksByTag[tag] = append(allChecksByTag[tag], checker.Name)
293298
}
294299
}
295300

296-
allTagsSorted := make([]string, 0, len(allChecksByTag))
297-
for t := range allChecksByTag {
298-
allTagsSorted = append(allTagsSorted, t)
299-
}
301+
allTagsSorted := maps.Keys(allChecksByTag)
300302
sort.Strings(allTagsSorted)
301303

302304
return &goCriticSettingsWrapper{
303-
GoCriticSettings: settings,
304-
logger: logger,
305-
allCheckers: allCheckers,
306-
allCheckersByName: allCheckersByName,
307-
allTagsSorted: allTagsSorted,
308-
allChecksByTag: allChecksByTag,
309-
inferredEnabledChecks: make(map[string]struct{}),
305+
GoCriticSettings: settings,
306+
logger: logger,
307+
allCheckers: allCheckers,
308+
allChecks: allChecks,
309+
allChecksLowerCased: allChecksLowerCased,
310+
allChecksByTag: allChecksByTag,
311+
allTagsSorted: allTagsSorted,
312+
inferredEnabledChecks: make(map[string]struct{}),
313+
inferredEnabledLowerCasedChecks: make(map[string]struct{}),
310314
}
311315
}
312316

313317
func (s *goCriticSettingsWrapper) GetLowerCasedParams() map[string]config.GoCriticCheckSettings {
314-
ret := make(map[string]config.GoCriticCheckSettings, len(s.SettingsPerCheck))
315-
316-
for checker, params := range s.SettingsPerCheck {
317-
ret[strings.ToLower(checker)] = params
318-
}
319-
320-
return ret
318+
return normalizeMap(s.SettingsPerCheck)
321319
}
322320

323321
// InferEnabledChecks tries to be consistent with (lintersdb.EnabledSet).build.
@@ -386,10 +384,11 @@ func (s *goCriticSettingsWrapper) InferEnabledChecks() {
386384
}
387385

388386
s.inferredEnabledChecks = enabledChecks
387+
s.inferredEnabledLowerCasedChecks = normalizeMap(s.inferredEnabledChecks)
389388
s.debugChecksFinalState()
390389
}
391390

392-
func (s *goCriticSettingsWrapper) buildEnabledAndDisabledByDefaultChecks() (enabled []string, disabled []string) {
391+
func (s *goCriticSettingsWrapper) buildEnabledAndDisabledByDefaultChecks() (enabled, disabled []string) {
393392
for _, info := range s.allCheckers {
394393
if enable := isEnabledByDefaultGoCriticChecker(info); enable {
395394
enabled = append(enabled, info.Name)
@@ -549,10 +548,11 @@ func (s *goCriticSettingsWrapper) validateCheckerNames() error {
549548
}
550549

551550
for name := range s.SettingsPerCheck {
552-
if !s.isKnownCheck(name) {
553-
return fmt.Errorf("invalid settings, check %q doesn't exist, see %s documentation", name, goCriticName)
551+
lcName := strings.ToLower(name)
552+
if !s.isKnownLowerCasedCheck(lcName) {
553+
return fmt.Errorf("invalid check settings: check %q doesn't exist, see %s documentation", name, goCriticName)
554554
}
555-
if !s.IsCheckEnabled(name) {
555+
if !s.isLowerCasedCheckEnabled(lcName) {
556556
s.logger.Warnf("%s: settings were provided for disabled check %q", goCriticName, name)
557557
}
558558
}
@@ -561,7 +561,12 @@ func (s *goCriticSettingsWrapper) validateCheckerNames() error {
561561
}
562562

563563
func (s *goCriticSettingsWrapper) isKnownCheck(name string) bool {
564-
_, ok := s.allCheckersByName[name]
564+
_, ok := s.allChecks[name]
565+
return ok
566+
}
567+
568+
func (s *goCriticSettingsWrapper) isKnownLowerCasedCheck(name string) bool {
569+
_, ok := s.allChecksLowerCased[name]
565570
return ok
566571
}
567572

@@ -588,6 +593,11 @@ func (s *goCriticSettingsWrapper) validateAtLeastOneCheckerEnabled() error {
588593
return nil
589594
}
590595

596+
func (s *goCriticSettingsWrapper) isLowerCasedCheckEnabled(name string) bool {
597+
_, ok := s.inferredEnabledLowerCasedChecks[name]
598+
return ok
599+
}
600+
591601
func (s *goCriticSettingsWrapper) IsCheckEnabled(name string) bool {
592602
_, ok := s.inferredEnabledChecks[name]
593603
return ok

pkg/golinters/gocritic_test.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,21 @@ import (
77
"github.com/go-critic/go-critic/checkers"
88
gocriticlinter "github.com/go-critic/go-critic/linter"
99
"github.com/stretchr/testify/assert"
10-
"github.com/stretchr/testify/require"
1110
"golang.org/x/exp/maps"
1211
"golang.org/x/exp/slices"
1312

1413
"github.com/golangci/golangci-lint/pkg/config"
1514
"github.com/golangci/golangci-lint/pkg/logutils"
1615
)
1716

17+
func init() {
18+
if err := checkers.InitEmbeddedRules(); err != nil {
19+
panic(err)
20+
}
21+
}
22+
1823
// https://go-critic.com/overview.html
1924
func Test_goCriticSettingsWrapper_InferEnabledChecks(t *testing.T) {
20-
err := checkers.InitEmbeddedRules()
21-
require.NoError(t, err)
22-
2325
allCheckersInfo := gocriticlinter.GetCheckersInfo()
2426

2527
allChecksByTag := make(map[string][]string)
@@ -361,7 +363,8 @@ func Test_goCriticSettingsWrapper_Validate(t *testing.T) {
361363
name: "settings for unknown check",
362364
sett: &config.GoCriticSettings{
363365
SettingsPerCheck: map[string]config.GoCriticCheckSettings{
364-
"captLocall": {"paramsOnly": false},
366+
"captLocall": {"paramsOnly": false},
367+
"unnamedResult": {"checkExported": true},
365368
},
366369
},
367370
expectedErr: true,
@@ -376,6 +379,17 @@ func Test_goCriticSettingsWrapper_Validate(t *testing.T) {
376379
},
377380
expectedErr: false, // Just logging.
378381
},
382+
{
383+
name: "settings by lower-cased checker name",
384+
sett: &config.GoCriticSettings{
385+
EnabledChecks: []string{"tooManyResultsChecker"},
386+
SettingsPerCheck: map[string]config.GoCriticCheckSettings{
387+
"toomanyresultschecker": {"maxResults": 3},
388+
"unnamedResult": {"checkExported": true},
389+
},
390+
},
391+
expectedErr: false,
392+
},
379393
{
380394
name: "enabled and disabled at one moment check",
381395
sett: &config.GoCriticSettings{
@@ -433,7 +447,9 @@ func Test_goCriticSettingsWrapper_Validate(t *testing.T) {
433447

434448
err := wr.Validate()
435449
if tt.expectedErr {
436-
assert.Error(t, err)
450+
if assert.Error(t, err) {
451+
t.Log(err)
452+
}
437453
} else {
438454
assert.NoError(t, err)
439455
}

pkg/lint/lintersdb/manager.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
464464
WithPresets(linter.PresetStyle).
465465
WithURL("https://github.com/jgautheron/goconst"),
466466

467-
linter.NewConfig(golinters.NewGoCritic(gocriticCfg, m.cfg.GetConfigDir())).
467+
linter.NewConfig(golinters.NewGoCritic(gocriticCfg, m.cfg.GetConfigDir)).
468468
WithSince("v1.12.0").
469469
WithPresets(linter.PresetStyle, linter.PresetMetaLinter).
470470
WithLoadForGoAnalysis().

test/testdata/configs/gocritic.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ linters-settings:
22
gocritic:
33
enabled-checks:
44
- rangeValCopy
5-
- flagDeref
6-
- wrapperFunc
75
- ruleguard
6+
disabled-checks:
7+
- dupSubExpr # So as not to overlap `ruleguard`.
88
settings:
99
rangeValCopy:
1010
sizeThreshold: 2

0 commit comments

Comments
 (0)