github.com/vanstinator/golangci-lint@v0.0.0-20240223191551-cc572f00d9d1/pkg/result/processors/identifier_marker.go (about) 1 package processors 2 3 import ( 4 "regexp" 5 6 "github.com/vanstinator/golangci-lint/pkg/result" 7 ) 8 9 type replacePattern struct { 10 re string 11 repl string 12 } 13 14 type replaceRegexp struct { 15 re *regexp.Regexp 16 repl string 17 } 18 19 var replacePatterns = []replacePattern{ 20 // unparam 21 {`^(\S+) - (\S+) is unused$`, "`${1}` - `${2}` is unused"}, 22 {`^(\S+) - (\S+) always receives (\S+) \((.*)\)$`, "`${1}` - `${2}` always receives `${3}` (`${4}`)"}, 23 {`^(\S+) - (\S+) always receives (.*)$`, "`${1}` - `${2}` always receives `${3}`"}, 24 {`^(\S+) - result (\S+) is always (\S+)`, "`${1}` - result `${2}` is always `${3}`"}, 25 26 // interfacer 27 {`^(\S+) can be (\S+)$`, "`${1}` can be `${2}`"}, 28 29 // govet 30 {`^printf: (\S+) arg list ends with redundant newline$`, "printf: `${1}` arg list ends with redundant newline"}, 31 {`^composites: (\S+) composite literal uses unkeyed fields$`, "composites: `${1}` composite literal uses unkeyed fields"}, 32 33 // gosec 34 {`^(\S+): Blacklisted import (\S+): weak cryptographic primitive$`, 35 "${1}: Blacklisted import `${2}`: weak cryptographic primitive"}, 36 {`^TLS InsecureSkipVerify set true.$`, "TLS `InsecureSkipVerify` set true."}, 37 38 // gosimple 39 {`should replace loop with (.*)$`, "should replace loop with `${1}`"}, 40 {`should use a simple channel send/receive instead of select with a single case`, 41 "should use a simple channel send/receive instead of `select` with a single case"}, 42 {`should omit comparison to bool constant, can be simplified to (.+)$`, 43 "should omit comparison to bool constant, can be simplified to `${1}`"}, 44 {`should write (.+) instead of (.+)$`, "should write `${1}` instead of `${2}`"}, 45 {`redundant return statement$`, "redundant `return` statement"}, 46 {`should replace this if statement with an unconditional strings.TrimPrefix`, 47 "should replace this `if` statement with an unconditional `strings.TrimPrefix`"}, 48 49 // staticcheck 50 {`this value of (\S+) is never used$`, "this value of `${1}` is never used"}, 51 {`should use time.Since instead of time.Now\(\).Sub$`, 52 "should use `time.Since` instead of `time.Now().Sub`"}, 53 {`should check returned error before deferring response.Close\(\)$`, 54 "should check returned error before deferring `response.Close()`"}, 55 {`no value of type uint is less than 0$`, "no value of type `uint` is less than `0`"}, 56 57 // unused 58 {`(func|const|field|type|var) (\S+) is unused$`, "${1} `${2}` is unused"}, 59 60 // typecheck 61 {`^unknown field (\S+) in struct literal$`, "unknown field `${1}` in struct literal"}, 62 {`^invalid operation: (\S+) \(variable of type (\S+)\) has no field or method (\S+)$`, 63 "invalid operation: `${1}` (variable of type `${2}`) has no field or method `${3}`"}, 64 {`^undeclared name: (\S+)$`, "undeclared name: `${1}`"}, 65 {`^cannot use addr \(variable of type (\S+)\) as (\S+) value in argument to (\S+)$`, 66 "cannot use addr (variable of type `${1}`) as `${2}` value in argument to `${3}`"}, 67 {`^other declaration of (\S+)$`, "other declaration of `${1}`"}, 68 {`^(\S+) redeclared in this block$`, "`${1}` redeclared in this block"}, 69 70 // golint 71 {`^exported (type|method|function|var|const) (\S+) should have comment or be unexported$`, 72 "exported ${1} `${2}` should have comment or be unexported"}, 73 {`^comment on exported (type|method|function|var|const) (\S+) should be of the form "(\S+) ..."$`, 74 "comment on exported ${1} `${2}` should be of the form `${3} ...`"}, 75 {`^should replace (.+) with (.+)$`, "should replace `${1}` with `${2}`"}, 76 {`^if block ends with a return statement, so drop this else and outdent its block$`, 77 "`if` block ends with a `return` statement, so drop this `else` and outdent its block"}, 78 {`^(struct field|var|range var|const|type|(?:func|method|interface method) (?:parameter|result)) (\S+) should be (\S+)$`, 79 "${1} `${2}` should be `${3}`"}, 80 {`^don't use underscores in Go names; var (\S+) should be (\S+)$`, 81 "don't use underscores in Go names; var `${1}` should be `${2}`"}, 82 } 83 84 type IdentifierMarker struct { 85 replaceRegexps []replaceRegexp 86 } 87 88 func NewIdentifierMarker() *IdentifierMarker { 89 var replaceRegexps []replaceRegexp 90 for _, p := range replacePatterns { 91 r := replaceRegexp{ 92 re: regexp.MustCompile(p.re), 93 repl: p.repl, 94 } 95 replaceRegexps = append(replaceRegexps, r) 96 } 97 98 return &IdentifierMarker{ 99 replaceRegexps: replaceRegexps, 100 } 101 } 102 103 func (im IdentifierMarker) Process(issues []result.Issue) ([]result.Issue, error) { 104 return transformIssues(issues, func(i *result.Issue) *result.Issue { 105 iCopy := *i 106 iCopy.Text = im.markIdentifiers(iCopy.Text) 107 return &iCopy 108 }), nil 109 } 110 111 func (im IdentifierMarker) markIdentifiers(s string) string { 112 for _, rr := range im.replaceRegexps { 113 rs := rr.re.ReplaceAllString(s, rr.repl) 114 if rs != s { 115 return rs 116 } 117 } 118 119 return s 120 } 121 122 func (im IdentifierMarker) Name() string { 123 return "identifier_marker" 124 } 125 func (im IdentifierMarker) Finish() {}