github.com/elek/golangci-lint@v1.42.2-0.20211208090441-c05b7fcb3a9a/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/elek/golangci-lint/pkg/config" 12 "github.com/elek/golangci-lint/pkg/logutils" 13 ) 14 15 var debugf = logutils.Debug("megacheck") 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 // TODO: uses "1.13" for backward compatibility, but in the future (v2) must be set by using build.Default.ReleaseTags like staticcheck. 28 return "1.13" 29 } 30 31 func setupStaticCheckAnalyzers(src []*lint.Analyzer, goVersion string, checks []string) []*analysis.Analyzer { 32 var names []string 33 for _, a := range src { 34 names = append(names, a.Analyzer.Name) 35 } 36 37 filter := filterAnalyzerNames(names, checks) 38 39 var ret []*analysis.Analyzer 40 for _, a := range src { 41 if filter[a.Analyzer.Name] { 42 setAnalyzerGoVersion(a.Analyzer, goVersion) 43 ret = append(ret, a.Analyzer) 44 } 45 } 46 47 return ret 48 } 49 50 func setAnalyzerGoVersion(a *analysis.Analyzer, goVersion string) { 51 if v := a.Flags.Lookup("go"); v != nil { 52 if err := v.Value.Set(goVersion); err != nil { 53 debugf("Failed to set go version: %s", err) 54 } 55 } 56 } 57 58 func staticCheckConfig(settings *config.StaticCheckSettings) *scconfig.Config { 59 var cfg *scconfig.Config 60 61 if settings == nil || !settings.HasConfiguration() { 62 return &scconfig.Config{ 63 Checks: []string{"*"}, // override for compatibility reason. Must drop in the next major version. 64 Initialisms: scconfig.DefaultConfig.Initialisms, 65 DotImportWhitelist: scconfig.DefaultConfig.DotImportWhitelist, 66 HTTPStatusCodeWhitelist: scconfig.DefaultConfig.HTTPStatusCodeWhitelist, 67 } 68 } 69 70 cfg = &scconfig.Config{ 71 Checks: settings.Checks, 72 Initialisms: settings.Initialisms, 73 DotImportWhitelist: settings.DotImportWhitelist, 74 HTTPStatusCodeWhitelist: settings.HTTPStatusCodeWhitelist, 75 } 76 77 if len(cfg.Checks) == 0 { 78 cfg.Checks = append(cfg.Checks, "*") // override for compatibility reason. Must drop in the next major version. 79 } 80 81 if len(cfg.Initialisms) == 0 { 82 cfg.Initialisms = append(cfg.Initialisms, scconfig.DefaultConfig.Initialisms...) 83 } 84 85 if len(cfg.DotImportWhitelist) == 0 { 86 cfg.DotImportWhitelist = append(cfg.DotImportWhitelist, scconfig.DefaultConfig.DotImportWhitelist...) 87 } 88 89 if len(cfg.HTTPStatusCodeWhitelist) == 0 { 90 cfg.HTTPStatusCodeWhitelist = append(cfg.HTTPStatusCodeWhitelist, scconfig.DefaultConfig.HTTPStatusCodeWhitelist...) 91 } 92 93 cfg.Checks = normalizeList(cfg.Checks) 94 cfg.Initialisms = normalizeList(cfg.Initialisms) 95 cfg.DotImportWhitelist = normalizeList(cfg.DotImportWhitelist) 96 cfg.HTTPStatusCodeWhitelist = normalizeList(cfg.HTTPStatusCodeWhitelist) 97 98 return cfg 99 } 100 101 // https://github.com/dominikh/go-tools/blob/9bf17c0388a65710524ba04c2d821469e639fdc2/lintcmd/lint.go#L437-L477 102 // nolint // 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 }