forked from golangci/golangci-lint
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathidentifier_marker.go
145 lines (132 loc) · 3.84 KB
/
identifier_marker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package processors
import (
"regexp"
"github.com/golangci/golangci-lint/pkg/result"
)
var _ Processor = (*IdentifierMarker)(nil)
type replacePattern struct {
exp *regexp.Regexp
repl string
}
// IdentifierMarker modifies report text.
// It must be before [Exclude] and [ExcludeRules]:
// users configure exclusions based on the modified text.
type IdentifierMarker struct {
patterns map[string][]replacePattern
}
func NewIdentifierMarker() *IdentifierMarker {
return &IdentifierMarker{
patterns: map[string][]replacePattern{
"unparam": {
{
exp: regexp.MustCompile(`^(\S+) - (\S+) is unused$`),
repl: "`${1}` - `${2}` is unused",
},
{
exp: regexp.MustCompile(`^(\S+) - (\S+) always receives (\S+) \((.*)\)$`),
repl: "`${1}` - `${2}` always receives `${3}` (`${4}`)",
},
{
exp: regexp.MustCompile(`^(\S+) - (\S+) always receives (.*)$`),
repl: "`${1}` - `${2}` always receives `${3}`",
},
{
exp: regexp.MustCompile(`^(\S+) - result (\S+) is always (\S+)`),
repl: "`${1}` - result `${2}` is always `${3}`",
},
},
"govet": {
{
// printf
exp: regexp.MustCompile(`^printf: (\S+) arg list ends with redundant newline$`),
repl: "printf: `${1}` arg list ends with redundant newline",
},
},
"gosec": {
{
exp: regexp.MustCompile(`^TLS InsecureSkipVerify set true.$`),
repl: "TLS `InsecureSkipVerify` set true.",
},
},
"gosimple": {
{
// s1011
exp: regexp.MustCompile(`should replace loop with (.*)$`),
repl: "should replace loop with `${1}`",
},
{
// s1000
exp: regexp.MustCompile(`should use a simple channel send/receive instead of select with a single case`),
repl: "should use a simple channel send/receive instead of `select` with a single case",
},
{
// s1002
exp: regexp.MustCompile(`should omit comparison to bool constant, can be simplified to (.+)$`),
repl: "should omit comparison to bool constant, can be simplified to `${1}`",
},
{
// s1023
exp: regexp.MustCompile(`redundant return statement$`),
repl: "redundant `return` statement",
},
{
// s1017
exp: regexp.MustCompile(`should replace this if statement with an unconditional strings.TrimPrefix`),
repl: "should replace this `if` statement with an unconditional `strings.TrimPrefix`",
},
},
"staticcheck": {
{
// sa4006
exp: regexp.MustCompile(`this value of (\S+) is never used$`),
repl: "this value of `${1}` is never used",
},
{
// s1012
exp: regexp.MustCompile(`should use time.Since instead of time.Now\(\).Sub$`),
repl: "should use `time.Since` instead of `time.Now().Sub`",
},
{
// sa5001
exp: regexp.MustCompile(`should check returned error before deferring response.Close\(\)$`),
repl: "should check returned error before deferring `response.Close()`",
},
{
// sa4003
exp: regexp.MustCompile(`no value of type uint is less than 0$`),
repl: "no value of type `uint` is less than `0`",
},
},
"unused": {
{
exp: regexp.MustCompile(`(func|const|field|type|var) (\S+) is unused$`),
repl: "${1} `${2}` is unused",
},
},
},
}
}
func (*IdentifierMarker) Name() string {
return "identifier_marker"
}
func (p *IdentifierMarker) Process(issues []result.Issue) ([]result.Issue, error) {
return transformIssues(issues, func(issue *result.Issue) *result.Issue {
re, ok := p.patterns[issue.FromLinter]
if !ok {
return issue
}
newIssue := *issue
newIssue.Text = markIdentifiers(re, newIssue.Text)
return &newIssue
}), nil
}
func (*IdentifierMarker) Finish() {}
func markIdentifiers(re []replacePattern, text string) string {
for _, rr := range re {
rs := rr.exp.ReplaceAllString(text, rr.repl)
if rs != text {
return rs
}
}
return text
}