1package linter
2
3import (
4	"golang.org/x/tools/go/packages"
5)
6
7const (
8	PresetBugs        = "bugs"        // Related to bugs detection.
9	PresetComment     = "comment"     // Related to comments analysis.
10	PresetComplexity  = "complexity"  // Related to code complexity analysis.
11	PresetError       = "error"       // Related to error handling analysis.
12	PresetFormatting  = "format"      // Related to code formatting.
13	PresetImport      = "import"      // Related to imports analysis.
14	PresetMetaLinter  = "metalinter"  // Related to linter that contains multiple rules or multiple linters.
15	PresetModule      = "module"      // Related to Go modules analysis.
16	PresetPerformance = "performance" // Related to performance.
17	PresetSQL         = "sql"         // Related to SQL.
18	PresetStyle       = "style"       // Related to coding style.
19	PresetTest        = "test"        // Related to the analysis of the code of the tests.
20	PresetUnused      = "unused"      // Related to the detection of unused code.
21)
22
23// LastLinter nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives.
24const LastLinter = "nolintlint"
25
26type Deprecation struct {
27	Since       string
28	Message     string
29	Replacement string
30}
31
32type Config struct {
33	Linter           Linter
34	EnabledByDefault bool
35
36	LoadMode packages.LoadMode
37
38	InPresets        []string
39	AlternativeNames []string
40
41	OriginalURL     string // URL of original (not forked) repo, needed for autogenerated README
42	CanAutoFix      bool
43	IsSlow          bool
44	DoesChangeTypes bool
45
46	Since       string
47	Deprecation *Deprecation
48}
49
50func (lc *Config) ConsiderSlow() *Config {
51	lc.IsSlow = true
52	return lc
53}
54
55func (lc *Config) IsSlowLinter() bool {
56	return lc.IsSlow
57}
58
59func (lc *Config) WithLoadFiles() *Config {
60	lc.LoadMode |= packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles
61	return lc
62}
63
64func (lc *Config) WithLoadForGoAnalysis() *Config {
65	lc = lc.WithLoadFiles()
66	lc.LoadMode |= packages.NeedImports | packages.NeedDeps | packages.NeedExportsFile | packages.NeedTypesSizes
67	lc.IsSlow = true
68	return lc
69}
70
71func (lc *Config) WithPresets(presets ...string) *Config {
72	lc.InPresets = presets
73	return lc
74}
75
76func (lc *Config) WithURL(url string) *Config {
77	lc.OriginalURL = url
78	return lc
79}
80
81func (lc *Config) WithAlternativeNames(names ...string) *Config {
82	lc.AlternativeNames = names
83	return lc
84}
85
86func (lc *Config) WithAutoFix() *Config {
87	lc.CanAutoFix = true
88	return lc
89}
90
91func (lc *Config) WithChangeTypes() *Config {
92	lc.DoesChangeTypes = true
93	return lc
94}
95
96func (lc *Config) WithSince(version string) *Config {
97	lc.Since = version
98	return lc
99}
100
101func (lc *Config) Deprecated(message, version, replacement string) *Config {
102	lc.Deprecation = &Deprecation{
103		Since:       version,
104		Message:     message,
105		Replacement: replacement,
106	}
107	return lc
108}
109
110func (lc *Config) IsDeprecated() bool {
111	return lc.Deprecation != nil
112}
113
114func (lc *Config) AllNames() []string {
115	return append([]string{lc.Name()}, lc.AlternativeNames...)
116}
117
118func (lc *Config) Name() string {
119	return lc.Linter.Name()
120}
121
122func NewConfig(linter Linter) *Config {
123	lc := &Config{
124		Linter: linter,
125	}
126	return lc.WithLoadFiles()
127}
128