github.com/nozzle/golangci-lint@v1.49.0-nz3/pkg/golinters/staticcheck_common.go (about) 1 package golinters 2 3 import ( 4 "strings" 5 "unicode" 6 7 "golang.org/x/tools/go/analysis" 8 "honnef.co/go/tools/analysis/lint" 9 scconfig "honnef.co/go/tools/config" 10 11 "github.com/golangci/golangci-lint/pkg/config" 12 "github.com/golangci/golangci-lint/pkg/logutils" 13 ) 14 15 var debugf = logutils.Debug(logutils.DebugKeyMegacheck) 16 17 func getGoVersion(settings *config.StaticCheckSettings) string { 18 var goVersion string 19 if settings != nil { 20 goVersion = settings.GoVersion 21 } 22 23 if goVersion != "" { 24 return goVersion 25 } 26 27 return "1.17" 28 } 29 30 func setupStaticCheckAnalyzers(src []*lint.Analyzer, goVersion string, checks []string) []*analysis.Analyzer { 31 var names []string 32 for _, a := range src { 33 names = append(names, a.Analyzer.Name) 34 } 35 36 filter := filterAnalyzerNames(names, checks) 37 38 var ret []*analysis.Analyzer 39 for _, a := range src { 40 if filter[a.Analyzer.Name] { 41 setAnalyzerGoVersion(a.Analyzer, goVersion) 42 ret = append(ret, a.Analyzer) 43 } 44 } 45 46 return ret 47 } 48 49 func setAnalyzerGoVersion(a *analysis.Analyzer, goVersion string) { 50 if v := a.Flags.Lookup("go"); v != nil { 51 if err := v.Value.Set(goVersion); err != nil { 52 debugf("Failed to set go version: %s", err) 53 } 54 } 55 } 56 57 func staticCheckConfig(settings *config.StaticCheckSettings) *scconfig.Config { 58 var cfg *scconfig.Config 59 60 if settings == nil || !settings.HasConfiguration() { 61 return &scconfig.Config{ 62 Checks: []string{"*"}, // override for compatibility reason. Must drop in the next major version. 63 Initialisms: scconfig.DefaultConfig.Initialisms, 64 DotImportWhitelist: scconfig.DefaultConfig.DotImportWhitelist, 65 HTTPStatusCodeWhitelist: scconfig.DefaultConfig.HTTPStatusCodeWhitelist, 66 } 67 } 68 69 cfg = &scconfig.Config{ 70 Checks: settings.Checks, 71 Initialisms: settings.Initialisms, 72 DotImportWhitelist: settings.DotImportWhitelist, 73 HTTPStatusCodeWhitelist: settings.HTTPStatusCodeWhitelist, 74 } 75 76 if len(cfg.Checks) == 0 { 77 cfg.Checks = append(cfg.Checks, "*") // override for compatibility reason. Must drop in the next major version. 78 } 79 80 if len(cfg.Initialisms) == 0 { 81 cfg.Initialisms = append(cfg.Initialisms, scconfig.DefaultConfig.Initialisms...) 82 } 83 84 if len(cfg.DotImportWhitelist) == 0 { 85 cfg.DotImportWhitelist = append(cfg.DotImportWhitelist, scconfig.DefaultConfig.DotImportWhitelist...) 86 } 87 88 if len(cfg.HTTPStatusCodeWhitelist) == 0 { 89 cfg.HTTPStatusCodeWhitelist = append(cfg.HTTPStatusCodeWhitelist, scconfig.DefaultConfig.HTTPStatusCodeWhitelist...) 90 } 91 92 cfg.Checks = normalizeList(cfg.Checks) 93 cfg.Initialisms = normalizeList(cfg.Initialisms) 94 cfg.DotImportWhitelist = normalizeList(cfg.DotImportWhitelist) 95 cfg.HTTPStatusCodeWhitelist = normalizeList(cfg.HTTPStatusCodeWhitelist) 96 97 return cfg 98 } 99 100 // https://github.com/dominikh/go-tools/blob/9bf17c0388a65710524ba04c2d821469e639fdc2/lintcmd/lint.go#L437-L477 101 // 102 //nolint:gocritic // Keep the original source code. 103 func filterAnalyzerNames(analyzers []string, checks []string) map[string]bool { 104 allowedChecks := map[string]bool{} 105 106 for _, check := range checks { 107 b := true 108 if len(check) > 1 && check[0] == '-' { 109 b = false 110 check = check[1:] 111 } 112 113 if check == "*" || check == "all" { 114 // Match all 115 for _, c := range analyzers { 116 allowedChecks[c] = b 117 } 118 } else if strings.HasSuffix(check, "*") { 119 // Glob 120 prefix := check[:len(check)-1] 121 isCat := strings.IndexFunc(prefix, func(r rune) bool { return unicode.IsNumber(r) }) == -1 122 123 for _, a := range analyzers { 124 idx := strings.IndexFunc(a, func(r rune) bool { return unicode.IsNumber(r) }) 125 if isCat { 126 // Glob is S*, which should match S1000 but not SA1000 127 cat := a[:idx] 128 if prefix == cat { 129 allowedChecks[a] = b 130 } 131 } else { 132 // Glob is S1* 133 if strings.HasPrefix(a, prefix) { 134 allowedChecks[a] = b 135 } 136 } 137 } 138 } else { 139 // Literal check name 140 allowedChecks[check] = b 141 } 142 } 143 return allowedChecks 144 } 145 146 // https://github.com/dominikh/go-tools/blob/9bf17c0388a65710524ba04c2d821469e639fdc2/config/config.go#L95-L116 147 func normalizeList(list []string) []string { 148 if len(list) > 1 { 149 nlist := make([]string, 0, len(list)) 150 nlist = append(nlist, list[0]) 151 for i, el := range list[1:] { 152 if el != list[i] { 153 nlist = append(nlist, el) 154 } 155 } 156 list = nlist 157 } 158 159 for _, el := range list { 160 if el == "inherit" { 161 // This should never happen, because the default config 162 // should not use "inherit" 163 panic(`unresolved "inherit"`) 164 } 165 } 166 167 return list 168 }