blob: 04b89d5629ebb14aad451fb61a01bd80f830cfdc [file] [log] [blame]
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package settings
import (
"fmt"
"log"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/gopls/internal/protocol"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/quickfix"
"honnef.co/go/tools/quickfix/qf1001"
"honnef.co/go/tools/quickfix/qf1002"
"honnef.co/go/tools/quickfix/qf1003"
"honnef.co/go/tools/quickfix/qf1004"
"honnef.co/go/tools/quickfix/qf1005"
"honnef.co/go/tools/quickfix/qf1006"
"honnef.co/go/tools/quickfix/qf1007"
"honnef.co/go/tools/quickfix/qf1008"
"honnef.co/go/tools/quickfix/qf1009"
"honnef.co/go/tools/quickfix/qf1010"
"honnef.co/go/tools/quickfix/qf1011"
"honnef.co/go/tools/quickfix/qf1012"
"honnef.co/go/tools/simple"
"honnef.co/go/tools/simple/s1000"
"honnef.co/go/tools/simple/s1001"
"honnef.co/go/tools/simple/s1002"
"honnef.co/go/tools/simple/s1003"
"honnef.co/go/tools/simple/s1004"
"honnef.co/go/tools/simple/s1005"
"honnef.co/go/tools/simple/s1006"
"honnef.co/go/tools/simple/s1007"
"honnef.co/go/tools/simple/s1008"
"honnef.co/go/tools/simple/s1009"
"honnef.co/go/tools/simple/s1010"
"honnef.co/go/tools/simple/s1011"
"honnef.co/go/tools/simple/s1012"
"honnef.co/go/tools/simple/s1016"
"honnef.co/go/tools/simple/s1017"
"honnef.co/go/tools/simple/s1018"
"honnef.co/go/tools/simple/s1019"
"honnef.co/go/tools/simple/s1020"
"honnef.co/go/tools/simple/s1021"
"honnef.co/go/tools/simple/s1023"
"honnef.co/go/tools/simple/s1024"
"honnef.co/go/tools/simple/s1025"
"honnef.co/go/tools/simple/s1028"
"honnef.co/go/tools/simple/s1029"
"honnef.co/go/tools/simple/s1030"
"honnef.co/go/tools/simple/s1031"
"honnef.co/go/tools/simple/s1032"
"honnef.co/go/tools/simple/s1033"
"honnef.co/go/tools/simple/s1034"
"honnef.co/go/tools/simple/s1035"
"honnef.co/go/tools/simple/s1036"
"honnef.co/go/tools/simple/s1037"
"honnef.co/go/tools/simple/s1038"
"honnef.co/go/tools/simple/s1039"
"honnef.co/go/tools/simple/s1040"
"honnef.co/go/tools/staticcheck"
"honnef.co/go/tools/staticcheck/sa1000"
"honnef.co/go/tools/staticcheck/sa1001"
"honnef.co/go/tools/staticcheck/sa1002"
"honnef.co/go/tools/staticcheck/sa1003"
"honnef.co/go/tools/staticcheck/sa1004"
"honnef.co/go/tools/staticcheck/sa1005"
"honnef.co/go/tools/staticcheck/sa1006"
"honnef.co/go/tools/staticcheck/sa1007"
"honnef.co/go/tools/staticcheck/sa1008"
"honnef.co/go/tools/staticcheck/sa1010"
"honnef.co/go/tools/staticcheck/sa1011"
"honnef.co/go/tools/staticcheck/sa1012"
"honnef.co/go/tools/staticcheck/sa1013"
"honnef.co/go/tools/staticcheck/sa1014"
"honnef.co/go/tools/staticcheck/sa1015"
"honnef.co/go/tools/staticcheck/sa1016"
"honnef.co/go/tools/staticcheck/sa1017"
"honnef.co/go/tools/staticcheck/sa1018"
"honnef.co/go/tools/staticcheck/sa1019"
"honnef.co/go/tools/staticcheck/sa1020"
"honnef.co/go/tools/staticcheck/sa1021"
"honnef.co/go/tools/staticcheck/sa1023"
"honnef.co/go/tools/staticcheck/sa1024"
"honnef.co/go/tools/staticcheck/sa1025"
"honnef.co/go/tools/staticcheck/sa1026"
"honnef.co/go/tools/staticcheck/sa1027"
"honnef.co/go/tools/staticcheck/sa1028"
"honnef.co/go/tools/staticcheck/sa1029"
"honnef.co/go/tools/staticcheck/sa1030"
"honnef.co/go/tools/staticcheck/sa1031"
"honnef.co/go/tools/staticcheck/sa1032"
"honnef.co/go/tools/staticcheck/sa2000"
"honnef.co/go/tools/staticcheck/sa2001"
"honnef.co/go/tools/staticcheck/sa2002"
"honnef.co/go/tools/staticcheck/sa2003"
"honnef.co/go/tools/staticcheck/sa3000"
"honnef.co/go/tools/staticcheck/sa3001"
"honnef.co/go/tools/staticcheck/sa4000"
"honnef.co/go/tools/staticcheck/sa4001"
"honnef.co/go/tools/staticcheck/sa4003"
"honnef.co/go/tools/staticcheck/sa4004"
"honnef.co/go/tools/staticcheck/sa4005"
"honnef.co/go/tools/staticcheck/sa4006"
"honnef.co/go/tools/staticcheck/sa4008"
"honnef.co/go/tools/staticcheck/sa4009"
"honnef.co/go/tools/staticcheck/sa4010"
"honnef.co/go/tools/staticcheck/sa4011"
"honnef.co/go/tools/staticcheck/sa4012"
"honnef.co/go/tools/staticcheck/sa4013"
"honnef.co/go/tools/staticcheck/sa4014"
"honnef.co/go/tools/staticcheck/sa4015"
"honnef.co/go/tools/staticcheck/sa4016"
"honnef.co/go/tools/staticcheck/sa4017"
"honnef.co/go/tools/staticcheck/sa4018"
"honnef.co/go/tools/staticcheck/sa4019"
"honnef.co/go/tools/staticcheck/sa4020"
"honnef.co/go/tools/staticcheck/sa4021"
"honnef.co/go/tools/staticcheck/sa4022"
"honnef.co/go/tools/staticcheck/sa4023"
"honnef.co/go/tools/staticcheck/sa4024"
"honnef.co/go/tools/staticcheck/sa4025"
"honnef.co/go/tools/staticcheck/sa4026"
"honnef.co/go/tools/staticcheck/sa4027"
"honnef.co/go/tools/staticcheck/sa4028"
"honnef.co/go/tools/staticcheck/sa4029"
"honnef.co/go/tools/staticcheck/sa4030"
"honnef.co/go/tools/staticcheck/sa4031"
"honnef.co/go/tools/staticcheck/sa4032"
"honnef.co/go/tools/staticcheck/sa5000"
"honnef.co/go/tools/staticcheck/sa5001"
"honnef.co/go/tools/staticcheck/sa5002"
"honnef.co/go/tools/staticcheck/sa5003"
"honnef.co/go/tools/staticcheck/sa5004"
"honnef.co/go/tools/staticcheck/sa5005"
"honnef.co/go/tools/staticcheck/sa5007"
"honnef.co/go/tools/staticcheck/sa5008"
"honnef.co/go/tools/staticcheck/sa5009"
"honnef.co/go/tools/staticcheck/sa5010"
"honnef.co/go/tools/staticcheck/sa5011"
"honnef.co/go/tools/staticcheck/sa5012"
"honnef.co/go/tools/staticcheck/sa6000"
"honnef.co/go/tools/staticcheck/sa6001"
"honnef.co/go/tools/staticcheck/sa6002"
"honnef.co/go/tools/staticcheck/sa6003"
"honnef.co/go/tools/staticcheck/sa6005"
"honnef.co/go/tools/staticcheck/sa6006"
"honnef.co/go/tools/staticcheck/sa9001"
"honnef.co/go/tools/staticcheck/sa9002"
"honnef.co/go/tools/staticcheck/sa9003"
"honnef.co/go/tools/staticcheck/sa9004"
"honnef.co/go/tools/staticcheck/sa9005"
"honnef.co/go/tools/staticcheck/sa9006"
"honnef.co/go/tools/staticcheck/sa9007"
"honnef.co/go/tools/staticcheck/sa9008"
"honnef.co/go/tools/staticcheck/sa9009"
"honnef.co/go/tools/stylecheck"
"honnef.co/go/tools/stylecheck/st1000"
"honnef.co/go/tools/stylecheck/st1001"
"honnef.co/go/tools/stylecheck/st1003"
"honnef.co/go/tools/stylecheck/st1005"
"honnef.co/go/tools/stylecheck/st1006"
"honnef.co/go/tools/stylecheck/st1008"
"honnef.co/go/tools/stylecheck/st1011"
"honnef.co/go/tools/stylecheck/st1012"
"honnef.co/go/tools/stylecheck/st1013"
"honnef.co/go/tools/stylecheck/st1015"
"honnef.co/go/tools/stylecheck/st1016"
"honnef.co/go/tools/stylecheck/st1017"
"honnef.co/go/tools/stylecheck/st1018"
"honnef.co/go/tools/stylecheck/st1019"
"honnef.co/go/tools/stylecheck/st1020"
"honnef.co/go/tools/stylecheck/st1021"
"honnef.co/go/tools/stylecheck/st1022"
"honnef.co/go/tools/stylecheck/st1023"
)
// StaticcheckAnalyzers lists available Staticcheck analyzers.
var StaticcheckAnalyzers = initStaticcheckAnalyzers()
func initStaticcheckAnalyzers() (res []*Analyzer) {
mapSeverity := func(severity lint.Severity) protocol.DiagnosticSeverity {
switch severity {
case lint.SeverityError:
return protocol.SeverityError
case lint.SeverityDeprecated:
// TODO(dh): in LSP, deprecated is a tag, not a severity.
// We'll want to support this once we enable SA5011.
return protocol.SeverityWarning
case lint.SeverityWarning:
return protocol.SeverityWarning
case lint.SeverityInfo:
return protocol.SeverityInformation
case lint.SeverityHint:
return protocol.SeverityHint
default:
return protocol.SeverityWarning
}
}
// We can't import buildir.Analyzer directly, so grab it from another analyzer.
buildir := sa1000.SCAnalyzer.Analyzer.Requires[0]
if buildir.Name != "buildir" {
panic("sa1000.Requires[0] is not buildir")
}
add := func(a *lint.Analyzer, dflt bool) {
// Assert that no analyzer that requires "buildir",
// even indirectly, is enabled by default.
if dflt {
var visit func(aa *analysis.Analyzer)
visit = func(aa *analysis.Analyzer) {
if aa == buildir {
log.Fatalf("%s requires buildir (perhaps indirectly) yet is enabled by default", a.Analyzer.Name)
}
for _, req := range aa.Requires {
visit(req)
}
}
visit(a.Analyzer)
}
res = append(res, &Analyzer{
analyzer: a.Analyzer,
staticcheck: a.Doc,
nonDefault: !dflt,
severity: mapSeverity(a.Doc.Severity),
})
}
type M = map[*lint.Analyzer]any // value = true|false|nil
addAll := func(suite string, upstream []*lint.Analyzer, config M) {
for _, a := range upstream {
v, ok := config[a]
if !ok {
panic(fmt.Sprintf("%s.Analyzers includes %s but config mapping does not; settings audit required", suite, a.Analyzer.Name))
}
if v != nil {
add(a, v.(bool))
}
}
}
// For each analyzer in the four suites provided by
// staticcheck, we provide a complete configuration, mapping
// it to a boolean, indicating whether it should be on by
// default in gopls, or nil to indicate explicitly that it has
// been excluded (e.g. because it is redundant with an
// existing vet analyzer such as printf, waitgroup, appends).
//
// This approach ensures that as suites grow, we make an
// affirmative decision, positive or negative, about adding
// new items.
//
// An analyzer may be off by default if:
// - it requires, even indirectly, "buildir", which is like
// buildssa but uses facts, making it expensive;
// - it has significant false positives;
// - it reports on non-problematic style issues;
// - its fixes are lossy (e.g. of comments) or not always sound;
// - it reports "maybes", not "definites" (e.g. sa9001).
// - it reports on harmless stylistic choices that may have
// been chosen deliberately for clarity or emphasis (e.g. s1005).
// - it makes deductions from build tags that are not true
// for all configurations.
addAll("simple", simple.Analyzers, M{
s1000.SCAnalyzer: true,
s1001.SCAnalyzer: true,
s1002.SCAnalyzer: false, // makes unsound deductions from build tags
s1003.SCAnalyzer: true,
s1004.SCAnalyzer: true,
s1005.SCAnalyzer: false, // not a correctness/style issue
s1006.SCAnalyzer: false, // makes unsound deductions from build tags
s1007.SCAnalyzer: true,
s1008.SCAnalyzer: false, // may lose important comments
s1009.SCAnalyzer: true,
s1010.SCAnalyzer: true,
s1011.SCAnalyzer: false, // requires buildir
s1012.SCAnalyzer: true,
s1016.SCAnalyzer: false, // may rely on coincidental structural subtyping
s1017.SCAnalyzer: true,
s1018.SCAnalyzer: true,
s1019.SCAnalyzer: true,
s1020.SCAnalyzer: true,
s1021.SCAnalyzer: false, // may lose important comments
s1023.SCAnalyzer: true,
s1024.SCAnalyzer: true,
s1025.SCAnalyzer: false, // requires buildir
s1028.SCAnalyzer: true,
s1029.SCAnalyzer: false, // requires buildir
s1030.SCAnalyzer: true, // (tentative: see docs,
s1031.SCAnalyzer: true,
s1032.SCAnalyzer: true,
s1033.SCAnalyzer: true,
s1034.SCAnalyzer: true,
s1035.SCAnalyzer: true,
s1036.SCAnalyzer: true,
s1037.SCAnalyzer: true,
s1038.SCAnalyzer: true,
s1039.SCAnalyzer: true,
s1040.SCAnalyzer: true,
})
addAll("stylecheck", stylecheck.Analyzers, M{
// These are all slightly too opinionated to be on by default.
st1000.SCAnalyzer: false,
st1001.SCAnalyzer: false,
st1003.SCAnalyzer: false,
st1005.SCAnalyzer: false,
st1006.SCAnalyzer: false,
st1008.SCAnalyzer: false,
st1011.SCAnalyzer: false,
st1012.SCAnalyzer: false,
st1013.SCAnalyzer: false,
st1015.SCAnalyzer: false,
st1016.SCAnalyzer: false,
st1017.SCAnalyzer: false,
st1018.SCAnalyzer: false,
st1019.SCAnalyzer: false,
st1020.SCAnalyzer: false,
st1021.SCAnalyzer: false,
st1022.SCAnalyzer: false,
st1023.SCAnalyzer: false,
})
// These are not bug fixes but code transformations: some
// reversible and value-neutral, of the kind typically listed
// on the VS Code's Refactor/Source Action/Quick Fix menus.
//
// TODO(adonovan): plumb these to the appropriate menu,
// as we do for code actions such as split/join lines.
addAll("quickfix", quickfix.Analyzers, M{
qf1001.SCAnalyzer: false, // not always a style improvement
qf1002.SCAnalyzer: true,
qf1003.SCAnalyzer: true,
qf1004.SCAnalyzer: true,
qf1005.SCAnalyzer: false, // not always a style improvement
qf1006.SCAnalyzer: false, // may lose important comments
qf1007.SCAnalyzer: false, // may lose important comments
qf1008.SCAnalyzer: false, // not always a style improvement
qf1009.SCAnalyzer: true,
qf1010.SCAnalyzer: true,
qf1011.SCAnalyzer: false, // not always a style improvement
qf1012.SCAnalyzer: true,
})
addAll("staticcheck", staticcheck.Analyzers, M{
sa1000.SCAnalyzer: false, // requires buildir
sa1001.SCAnalyzer: true,
sa1002.SCAnalyzer: false, // requires buildir
sa1003.SCAnalyzer: false, // requires buildir
sa1004.SCAnalyzer: true,
sa1005.SCAnalyzer: true,
sa1006.SCAnalyzer: nil, // redundant wrt 'printf'
sa1007.SCAnalyzer: false, // requires buildir
sa1008.SCAnalyzer: true,
sa1010.SCAnalyzer: false, // requires buildir
sa1011.SCAnalyzer: false, // requires buildir
sa1012.SCAnalyzer: true,
sa1013.SCAnalyzer: true,
sa1014.SCAnalyzer: false, // requires buildir
sa1015.SCAnalyzer: false, // requires buildir
sa1016.SCAnalyzer: true,
sa1017.SCAnalyzer: false, // requires buildir
sa1018.SCAnalyzer: false, // requires buildir
sa1019.SCAnalyzer: nil, // redundant wrt 'deprecated'
sa1020.SCAnalyzer: false, // requires buildir
sa1021.SCAnalyzer: false, // requires buildir
sa1023.SCAnalyzer: false, // requires buildir
sa1024.SCAnalyzer: false, // requires buildir
sa1025.SCAnalyzer: false, // requires buildir
sa1026.SCAnalyzer: false, // requires buildir
sa1027.SCAnalyzer: false, // requires buildir
sa1028.SCAnalyzer: false, // requires buildir
sa1029.SCAnalyzer: false, // requires buildir
sa1030.SCAnalyzer: false, // requires buildir
sa1031.SCAnalyzer: false, // requires buildir
sa1032.SCAnalyzer: false, // requires buildir
sa2000.SCAnalyzer: nil, // redundant wrt 'waitgroup'
sa2001.SCAnalyzer: true,
sa2002.SCAnalyzer: false, // requires buildir
sa2003.SCAnalyzer: false, // requires buildir
sa3000.SCAnalyzer: true,
sa3001.SCAnalyzer: true,
sa4000.SCAnalyzer: true,
sa4001.SCAnalyzer: true,
sa4003.SCAnalyzer: true,
sa4004.SCAnalyzer: true,
sa4005.SCAnalyzer: false, // requires buildir
sa4006.SCAnalyzer: false, // requires buildir
sa4008.SCAnalyzer: false, // requires buildir
sa4009.SCAnalyzer: false, // requires buildir
sa4010.SCAnalyzer: false, // requires buildir
sa4011.SCAnalyzer: true,
sa4012.SCAnalyzer: false, // requires buildir
sa4013.SCAnalyzer: true,
sa4014.SCAnalyzer: true,
sa4015.SCAnalyzer: false, // requires buildir
sa4016.SCAnalyzer: true,
sa4017.SCAnalyzer: false, // requires buildir
sa4018.SCAnalyzer: false, // requires buildir
sa4019.SCAnalyzer: true,
sa4020.SCAnalyzer: true,
sa4021.SCAnalyzer: nil, // redundant wrt 'appends'
sa4022.SCAnalyzer: true,
sa4023.SCAnalyzer: false, // requires buildir
sa4024.SCAnalyzer: true,
sa4025.SCAnalyzer: true,
sa4026.SCAnalyzer: true,
sa4027.SCAnalyzer: true,
sa4028.SCAnalyzer: true,
sa4029.SCAnalyzer: true,
sa4030.SCAnalyzer: true,
sa4031.SCAnalyzer: false, // requires buildir
sa4032.SCAnalyzer: true,
sa5000.SCAnalyzer: false, // requires buildir
sa5001.SCAnalyzer: true,
sa5002.SCAnalyzer: false, // makes unsound deductions from build tags
sa5003.SCAnalyzer: true,
sa5004.SCAnalyzer: true,
sa5005.SCAnalyzer: false, // requires buildir
sa5007.SCAnalyzer: false, // requires buildir
sa5008.SCAnalyzer: true,
sa5009.SCAnalyzer: nil, // requires buildir; redundant wrt 'printf' (#34494)
sa5010.SCAnalyzer: false, // requires buildir
sa5011.SCAnalyzer: false, // requires buildir
sa5012.SCAnalyzer: false, // requires buildir
sa6000.SCAnalyzer: false, // requires buildir
sa6001.SCAnalyzer: false, // requires buildir
sa6002.SCAnalyzer: false, // requires buildir
sa6003.SCAnalyzer: false, // requires buildir
sa6005.SCAnalyzer: true,
sa6006.SCAnalyzer: true,
sa9001.SCAnalyzer: false, // reports a "maybe" bug (low signal/noise)
sa9002.SCAnalyzer: true,
sa9003.SCAnalyzer: false, // requires buildir; NonDefault
sa9004.SCAnalyzer: true,
sa9005.SCAnalyzer: false, // requires buildir
sa9006.SCAnalyzer: true,
sa9007.SCAnalyzer: false, // requires buildir
sa9008.SCAnalyzer: false, // requires buildir
sa9009.SCAnalyzer: true,
})
return res
}