@@ -15,17 +15,26 @@ import (
1515
1616const gocriticDebugKey = "gocritic"
1717
18- var gocriticDebugf = logutils .Debug (gocriticDebugKey )
19- var isGocriticDebug = logutils .HaveDebugTag (gocriticDebugKey )
20-
21- var allGocriticCheckers = lintpack .GetCheckersInfo ()
18+ var (
19+ gocriticDebugf = logutils .Debug (gocriticDebugKey )
20+ isGocriticDebug = logutils .HaveDebugTag (gocriticDebugKey )
21+ allGocriticCheckers = lintpack .GetCheckersInfo ()
22+ allGocriticCheckerMap = func () map [string ]* lintpack.CheckerInfo {
23+ checkInfoMap := make (map [string ]* lintpack.CheckerInfo )
24+ for _ , checkInfo := range allGocriticCheckers {
25+ checkInfoMap [checkInfo .Name ] = checkInfo
26+ }
27+ return checkInfoMap
28+ }()
29+ )
2230
2331type GocriticCheckSettings map [string ]interface {}
2432
2533type GocriticSettings struct {
2634 EnabledChecks []string `mapstructure:"enabled-checks"`
2735 DisabledChecks []string `mapstructure:"disabled-checks"`
2836 EnabledTags []string `mapstructure:"enabled-tags"`
37+ DisabledTags []string `mapstructure:"disabled-tags"`
2938 SettingsPerCheck map [string ]GocriticCheckSettings `mapstructure:"settings"`
3039
3140 inferredEnabledChecks map [string ]bool
@@ -107,6 +116,8 @@ func (s *GocriticSettings) InferEnabledChecks(log logutils.Log) {
107116 debugChecksListf (disabledByDefaultChecks , "Disabled by default" )
108117
109118 var enabledChecks []string
119+
120+ // EnabledTags
110121 if len (s .EnabledTags ) != 0 {
111122 tagToCheckers := buildGocriticTagToCheckersMap ()
112123 for _ , tag := range s .EnabledTags {
@@ -120,6 +131,12 @@ func (s *GocriticSettings) InferEnabledChecks(log logutils.Log) {
120131 enabledChecks = append (enabledChecks , enabledByDefaultChecks ... )
121132 }
122133
134+ // DisabledTags
135+ if len (s .DisabledTags ) != 0 {
136+ enabledChecks = filterByDisableTags (enabledChecks , s .DisabledTags , log )
137+ }
138+
139+ // EnabledChecks
123140 if len (s .EnabledChecks ) != 0 {
124141 debugChecksListf (s .EnabledChecks , "Enabled by config" )
125142
@@ -133,6 +150,7 @@ func (s *GocriticSettings) InferEnabledChecks(log logutils.Log) {
133150 }
134151 }
135152
153+ // DisabledChecks
136154 if len (s .DisabledChecks ) != 0 {
137155 debugChecksListf (s .DisabledChecks , "Disabled by config" )
138156
@@ -174,6 +192,22 @@ func validateStringsUniq(ss []string) error {
174192 return nil
175193}
176194
195+ func intersectStringSlice (s1 , s2 []string ) []string {
196+ s1Map := make (map [string ]struct {})
197+ for _ , s := range s1 {
198+ s1Map [s ] = struct {}{}
199+ }
200+
201+ result := make ([]string , 0 )
202+ for _ , s := range s2 {
203+ if _ , exists := s1Map [s ]; exists {
204+ result = append (result , s )
205+ }
206+ }
207+
208+ return result
209+ }
210+
177211func (s * GocriticSettings ) Validate (log logutils.Log ) error {
178212 if len (s .EnabledTags ) == 0 {
179213 if len (s .EnabledChecks ) != 0 && len (s .DisabledChecks ) != 0 {
@@ -187,7 +221,16 @@ func (s *GocriticSettings) Validate(log logutils.Log) error {
187221 tagToCheckers := buildGocriticTagToCheckersMap ()
188222 for _ , tag := range s .EnabledTags {
189223 if _ , ok := tagToCheckers [tag ]; ! ok {
190- return fmt .Errorf ("gocritic tag %q doesn't exist" , tag )
224+ return fmt .Errorf ("gocritic [enabled]tag %q doesn't exist" , tag )
225+ }
226+ }
227+ }
228+
229+ if len (s .DisabledTags ) > 0 {
230+ tagToCheckers := buildGocriticTagToCheckersMap ()
231+ for _ , tag := range s .EnabledTags {
232+ if _ , ok := tagToCheckers [tag ]; ! ok {
233+ return fmt .Errorf ("gocritic [disabled]tag %q doesn't exist" , tag )
191234 }
192235 }
193236 }
@@ -301,3 +344,24 @@ func (s *GocriticSettings) GetLowercasedParams() map[string]GocriticCheckSetting
301344 }
302345 return ret
303346}
347+
348+ func filterByDisableTags (enabledChecks , disableTags []string , log logutils.Log ) []string {
349+ enabledChecksSet := stringsSliceToSet (enabledChecks )
350+ for _ , enabledCheck := range enabledChecks {
351+ checkInfo , checkInfoExists := allGocriticCheckerMap [enabledCheck ]
352+ if ! checkInfoExists {
353+ log .Warnf ("Gocritic check %q was not exists via filtering disabled tags" , enabledCheck )
354+ continue
355+ }
356+ hitTags := intersectStringSlice (checkInfo .Tags , disableTags )
357+ if len (hitTags ) != 0 {
358+ delete (enabledChecksSet , enabledCheck )
359+ }
360+ debugChecksListf (enabledChecks , "Disabled by config tags %s" , sprintStrings (disableTags ))
361+ }
362+ enabledChecks = nil
363+ for enabledCheck := range enabledChecksSet {
364+ enabledChecks = append (enabledChecks , enabledCheck )
365+ }
366+ return enabledChecks
367+ }
0 commit comments