Update nolintlint to fix nolint formatting and remove unused nolint statements (#1573)
Also allow multiple ranges to satisfy a nolint statement as having been used.
This commit is contained in:
parent
df9278efd2
commit
aeb9830329
@ -72,6 +72,7 @@ func NewNoLintLint() *goanalysis.Linter {
|
|||||||
Pos: i.Position(),
|
Pos: i.Position(),
|
||||||
ExpectNoLint: expectNoLint,
|
ExpectNoLint: expectNoLint,
|
||||||
ExpectedNoLintLinter: expectedNolintLinter,
|
ExpectedNoLintLinter: expectedNolintLinter,
|
||||||
|
Replacement: i.Replacement(),
|
||||||
}
|
}
|
||||||
res = append(res, goanalysis.NewIssue(issue, pass))
|
res = append(res, goanalysis.NewIssue(issue, pass))
|
||||||
}
|
}
|
||||||
|
@ -8,16 +8,21 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/golangci/golangci-lint/pkg/result"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BaseIssue struct {
|
type BaseIssue struct {
|
||||||
fullDirective string
|
fullDirective string
|
||||||
directiveWithOptionalLeadingSpace string
|
directiveWithOptionalLeadingSpace string
|
||||||
position token.Position
|
position token.Position
|
||||||
|
replacement *result.Replacement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BaseIssue) Position() token.Position {
|
func (b BaseIssue) Position() token.Position { return b.position }
|
||||||
return b.position
|
|
||||||
|
func (b BaseIssue) Replacement() *result.Replacement {
|
||||||
|
return b.replacement
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExtraLeadingSpace struct {
|
type ExtraLeadingSpace struct {
|
||||||
@ -85,7 +90,7 @@ type UnusedCandidate struct {
|
|||||||
func (i UnusedCandidate) Details() string {
|
func (i UnusedCandidate) Details() string {
|
||||||
details := fmt.Sprintf("directive `%s` is unused", i.fullDirective)
|
details := fmt.Sprintf("directive `%s` is unused", i.fullDirective)
|
||||||
if i.ExpectedLinter != "" {
|
if i.ExpectedLinter != "" {
|
||||||
details += fmt.Sprintf(" for linter %s", i.ExpectedLinter)
|
details += fmt.Sprintf(" for linter %q", i.ExpectedLinter)
|
||||||
}
|
}
|
||||||
return details
|
return details
|
||||||
}
|
}
|
||||||
@ -100,6 +105,7 @@ type Issue interface {
|
|||||||
Details() string
|
Details() string
|
||||||
Position() token.Position
|
Position() token.Position
|
||||||
String() string
|
String() string
|
||||||
|
Replacement() *result.Replacement
|
||||||
}
|
}
|
||||||
|
|
||||||
type Needs uint
|
type Needs uint
|
||||||
@ -115,7 +121,7 @@ const (
|
|||||||
var commentPattern = regexp.MustCompile(`^//\s*(nolint)(:\s*[\w-]+\s*(?:,\s*[\w-]+\s*)*)?\b`)
|
var commentPattern = regexp.MustCompile(`^//\s*(nolint)(:\s*[\w-]+\s*(?:,\s*[\w-]+\s*)*)?\b`)
|
||||||
|
|
||||||
// matches a complete nolint directive
|
// matches a complete nolint directive
|
||||||
var fullDirectivePattern = regexp.MustCompile(`^//\s*nolint(:\s*[\w-]+\s*(?:,\s*[\w-]+\s*)*)?\s*(//.*)?\s*\n?$`)
|
var fullDirectivePattern = regexp.MustCompile(`^//\s*nolint(?::(\s*[\w-]+\s*(?:,\s*[\w-]+\s*)*))?\s*(//.*)?\s*\n?$`)
|
||||||
|
|
||||||
type Linter struct {
|
type Linter struct {
|
||||||
excludes []string // lists individual linters that don't require explanations
|
excludes []string // lists individual linters that don't require explanations
|
||||||
@ -164,19 +170,34 @@ func (l Linter) Run(fset *token.FileSet, nodes ...ast.Node) ([]Issue, error) {
|
|||||||
directiveWithOptionalLeadingSpace = "// " + strings.TrimSpace(split[1])
|
directiveWithOptionalLeadingSpace = "// " + strings.TrimSpace(split[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pos := fset.Position(comment.Pos())
|
||||||
|
end := fset.Position(comment.End())
|
||||||
|
|
||||||
base := BaseIssue{
|
base := BaseIssue{
|
||||||
fullDirective: comment.Text,
|
fullDirective: comment.Text,
|
||||||
directiveWithOptionalLeadingSpace: directiveWithOptionalLeadingSpace,
|
directiveWithOptionalLeadingSpace: directiveWithOptionalLeadingSpace,
|
||||||
position: fset.Position(comment.Pos()),
|
position: pos,
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for, report and eliminate leading spaces so we can check for other issues
|
// check for, report and eliminate leading spaces so we can check for other issues
|
||||||
if len(leadingSpace) > 1 {
|
if len(leadingSpace) > 0 {
|
||||||
issues = append(issues, ExtraLeadingSpace{BaseIssue: base})
|
machineReadableReplacement := &result.Replacement{
|
||||||
|
Inline: &result.InlineFix{
|
||||||
|
StartCol: pos.Column - 1,
|
||||||
|
Length: len(leadingSpace) + 2,
|
||||||
|
NewString: "//",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l.needs&NeedsMachineOnly) != 0 && len(leadingSpace) > 0 {
|
if (l.needs & NeedsMachineOnly) != 0 {
|
||||||
issues = append(issues, NotMachine{BaseIssue: base})
|
issue := NotMachine{BaseIssue: base}
|
||||||
|
issue.BaseIssue.replacement = machineReadableReplacement
|
||||||
|
issues = append(issues, issue)
|
||||||
|
} else if len(leadingSpace) > 1 {
|
||||||
|
issue := ExtraLeadingSpace{BaseIssue: base}
|
||||||
|
issue.BaseIssue.replacement = machineReadableReplacement
|
||||||
|
issues = append(issues, issue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fullMatches := fullDirectivePattern.FindStringSubmatch(comment.Text)
|
fullMatches := fullDirectivePattern.FindStringSubmatch(comment.Text)
|
||||||
@ -188,7 +209,7 @@ func (l Linter) Run(fset *token.FileSet, nodes ...ast.Node) ([]Issue, error) {
|
|||||||
lintersText, explanation := fullMatches[1], fullMatches[2]
|
lintersText, explanation := fullMatches[1], fullMatches[2]
|
||||||
var linters []string
|
var linters []string
|
||||||
if len(lintersText) > 0 {
|
if len(lintersText) > 0 {
|
||||||
lls := strings.Split(lintersText[1:], ",")
|
lls := strings.Split(lintersText, ",")
|
||||||
linters = make([]string, 0, len(lls))
|
linters = make([]string, 0, len(lls))
|
||||||
for _, ll := range lls {
|
for _, ll := range lls {
|
||||||
ll = strings.TrimSpace(ll)
|
ll = strings.TrimSpace(ll)
|
||||||
@ -206,11 +227,34 @@ func (l Linter) Run(fset *token.FileSet, nodes ...ast.Node) ([]Issue, error) {
|
|||||||
|
|
||||||
// when detecting unused directives, we send all the directives through and filter them out in the nolint processor
|
// when detecting unused directives, we send all the directives through and filter them out in the nolint processor
|
||||||
if (l.needs & NeedsUnused) != 0 {
|
if (l.needs & NeedsUnused) != 0 {
|
||||||
|
removeNolintCompletely := &result.Replacement{
|
||||||
|
Inline: &result.InlineFix{
|
||||||
|
StartCol: pos.Column - 1,
|
||||||
|
Length: end.Column - pos.Column,
|
||||||
|
NewString: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
if len(linters) == 0 {
|
if len(linters) == 0 {
|
||||||
issues = append(issues, UnusedCandidate{BaseIssue: base})
|
issue := UnusedCandidate{BaseIssue: base}
|
||||||
|
issue.replacement = removeNolintCompletely
|
||||||
|
issues = append(issues, issue)
|
||||||
} else {
|
} else {
|
||||||
for _, linter := range linters {
|
for i, linter := range linters {
|
||||||
issues = append(issues, UnusedCandidate{BaseIssue: base, ExpectedLinter: linter})
|
issue := UnusedCandidate{BaseIssue: base, ExpectedLinter: linter}
|
||||||
|
replacement := removeNolintCompletely
|
||||||
|
if len(linters) > 1 {
|
||||||
|
otherLinters := append(append([]string(nil), linters[0:i]...), linters[i+1:]...)
|
||||||
|
replacement = &result.Replacement{
|
||||||
|
Inline: &result.InlineFix{
|
||||||
|
StartCol: (pos.Column - 1) + len("//") + len(leadingSpace) + len("nolint:"),
|
||||||
|
Length: len(lintersText) - 1,
|
||||||
|
NewString: strings.Join(otherLinters, ","),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
issue.replacement = replacement
|
||||||
|
issues = append(issues, issue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,22 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/golangci/golangci-lint/pkg/result"
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:funlen
|
//nolint:funlen
|
||||||
func TestNoLintLint(t *testing.T) {
|
func TestNoLintLint(t *testing.T) {
|
||||||
|
type issueWithReplacement struct {
|
||||||
|
issue string
|
||||||
|
replacement *result.Replacement
|
||||||
|
}
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
needs Needs
|
needs Needs
|
||||||
excludes []string
|
excludes []string
|
||||||
contents string
|
contents string
|
||||||
expected []string
|
expected []issueWithReplacement
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
desc: "when no explanation is provided",
|
desc: "when no explanation is provided",
|
||||||
@ -33,11 +39,11 @@ func foo() {
|
|||||||
good() //nolint // this is ok
|
good() //nolint // this is ok
|
||||||
other() //nolintother
|
other() //nolintother
|
||||||
}`,
|
}`,
|
||||||
expected: []string{
|
expected: []issueWithReplacement{
|
||||||
"directive `//nolint` should provide explanation such as `//nolint // this is why` at testing.go:5:1",
|
{"directive `//nolint` should provide explanation such as `//nolint // this is why` at testing.go:5:1", nil},
|
||||||
"directive `//nolint` should provide explanation such as `//nolint // this is why` at testing.go:7:9",
|
{"directive `//nolint` should provide explanation such as `//nolint // this is why` at testing.go:7:9", nil},
|
||||||
"directive `//nolint //` should provide explanation such as `//nolint // this is why` at testing.go:8:9",
|
{"directive `//nolint //` should provide explanation such as `//nolint // this is why` at testing.go:8:9", nil},
|
||||||
"directive `//nolint // ` should provide explanation such as `//nolint // this is why` at testing.go:9:9",
|
{"directive `//nolint // ` should provide explanation such as `//nolint // this is why` at testing.go:9:9", nil},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -50,8 +56,8 @@ package bar
|
|||||||
//nolint // this is ok
|
//nolint // this is ok
|
||||||
//nolint:dupl
|
//nolint:dupl
|
||||||
func foo() {}`,
|
func foo() {}`,
|
||||||
expected: []string{
|
expected: []issueWithReplacement{
|
||||||
"directive `//nolint:dupl` should provide explanation such as `//nolint:dupl // this is why` at testing.go:6:1",
|
{"directive `//nolint:dupl` should provide explanation such as `//nolint:dupl // this is why` at testing.go:6:1", nil},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -76,9 +82,9 @@ func foo() {
|
|||||||
bad() //nolint
|
bad() //nolint
|
||||||
bad() // nolint // because
|
bad() // nolint // because
|
||||||
}`,
|
}`,
|
||||||
expected: []string{
|
expected: []issueWithReplacement{
|
||||||
"directive `//nolint` should mention specific linter such as `//nolint:my-linter` at testing.go:6:9",
|
{"directive `//nolint` should mention specific linter such as `//nolint:my-linter` at testing.go:6:9", nil},
|
||||||
"directive `// nolint // because` should mention specific linter such as `// nolint:my-linter` at testing.go:7:9",
|
{"directive `// nolint // because` should mention specific linter such as `// nolint:my-linter` at testing.go:7:9", nil},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -91,8 +97,17 @@ func foo() {
|
|||||||
bad() // nolint
|
bad() // nolint
|
||||||
good() //nolint
|
good() //nolint
|
||||||
}`,
|
}`,
|
||||||
expected: []string{
|
expected: []issueWithReplacement{
|
||||||
|
{
|
||||||
"directive `// nolint` should be written without leading space as `//nolint` at testing.go:5:9",
|
"directive `// nolint` should be written without leading space as `//nolint` at testing.go:5:9",
|
||||||
|
&result.Replacement{
|
||||||
|
Inline: &result.InlineFix{
|
||||||
|
StartCol: 8,
|
||||||
|
Length: 3,
|
||||||
|
NewString: "//",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -104,8 +119,17 @@ func foo() {
|
|||||||
bad() // nolint
|
bad() // nolint
|
||||||
good() // nolint
|
good() // nolint
|
||||||
}`,
|
}`,
|
||||||
expected: []string{
|
expected: []issueWithReplacement{
|
||||||
|
{
|
||||||
"directive `// nolint` should not have more than one leading space at testing.go:5:9",
|
"directive `// nolint` should not have more than one leading space at testing.go:5:9",
|
||||||
|
&result.Replacement{
|
||||||
|
Inline: &result.InlineFix{
|
||||||
|
StartCol: 8,
|
||||||
|
Length: 4,
|
||||||
|
NewString: "//",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -119,8 +143,8 @@ func foo() {
|
|||||||
good() // nolint: linter1,linter2
|
good() // nolint: linter1,linter2
|
||||||
good() // nolint: linter1, linter2
|
good() // nolint: linter1, linter2
|
||||||
}`,
|
}`,
|
||||||
expected: []string{
|
expected: []issueWithReplacement{
|
||||||
"directive `// nolint:linter1 linter2` should match `// nolint[:<comma-separated-linters>] [// <explanation>]` at testing.go:6:9", //nolint:lll // this is a string
|
{"directive `// nolint:linter1 linter2` should match `// nolint[:<comma-separated-linters>] [// <explanation>]` at testing.go:6:9", nil}, //nolint:lll // this is a string
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -133,6 +157,92 @@ func foo() {
|
|||||||
// something else
|
// something else
|
||||||
}`,
|
}`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "needs unused without specific linter generates replacement",
|
||||||
|
needs: NeedsUnused,
|
||||||
|
contents: `
|
||||||
|
package bar
|
||||||
|
|
||||||
|
func foo() {
|
||||||
|
bad() //nolint
|
||||||
|
}`,
|
||||||
|
expected: []issueWithReplacement{
|
||||||
|
{
|
||||||
|
"directive `//nolint` is unused at testing.go:5:9",
|
||||||
|
&result.Replacement{
|
||||||
|
Inline: &result.InlineFix{
|
||||||
|
StartCol: 8,
|
||||||
|
Length: 8,
|
||||||
|
NewString: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "needs unused with one specific linter generates replacement",
|
||||||
|
needs: NeedsUnused,
|
||||||
|
contents: `
|
||||||
|
package bar
|
||||||
|
|
||||||
|
func foo() {
|
||||||
|
bad() //nolint:somelinter
|
||||||
|
}`,
|
||||||
|
expected: []issueWithReplacement{
|
||||||
|
{
|
||||||
|
"directive `//nolint:somelinter` is unused for linter \"somelinter\" at testing.go:5:9",
|
||||||
|
&result.Replacement{
|
||||||
|
Inline: &result.InlineFix{
|
||||||
|
StartCol: 8,
|
||||||
|
Length: 19,
|
||||||
|
NewString: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "needs unused with multiple specific linter generates replacement for each linter",
|
||||||
|
needs: NeedsUnused,
|
||||||
|
contents: `
|
||||||
|
package bar
|
||||||
|
|
||||||
|
func foo() {
|
||||||
|
bad() //nolint:linter1,linter2,linter3
|
||||||
|
}`,
|
||||||
|
expected: []issueWithReplacement{
|
||||||
|
{
|
||||||
|
"directive `//nolint:linter1,linter2,linter3` is unused for linter \"linter1\" at testing.go:5:9",
|
||||||
|
&result.Replacement{
|
||||||
|
Inline: &result.InlineFix{
|
||||||
|
StartCol: 17,
|
||||||
|
Length: 22,
|
||||||
|
NewString: "linter2,linter3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directive `//nolint:linter1,linter2,linter3` is unused for linter \"linter2\" at testing.go:5:9",
|
||||||
|
&result.Replacement{
|
||||||
|
Inline: &result.InlineFix{
|
||||||
|
StartCol: 17,
|
||||||
|
Length: 22,
|
||||||
|
NewString: "linter1,linter3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directive `//nolint:linter1,linter2,linter3` is unused for linter \"linter3\" at testing.go:5:9",
|
||||||
|
&result.Replacement{
|
||||||
|
Inline: &result.InlineFix{
|
||||||
|
StartCol: 17,
|
||||||
|
Length: 22,
|
||||||
|
NewString: "linter1,linter2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
@ -149,12 +259,16 @@ func foo() {
|
|||||||
actualIssues, err := linter.Run(fset, expr)
|
actualIssues, err := linter.Run(fset, expr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
actualIssueStrs := make([]string, 0, len(actualIssues))
|
actualIssuesWithReplacements := make([]issueWithReplacement, 0, len(actualIssues))
|
||||||
for _, i := range actualIssues {
|
for _, i := range actualIssues {
|
||||||
actualIssueStrs = append(actualIssueStrs, i.String())
|
actualIssuesWithReplacements = append(actualIssuesWithReplacements, issueWithReplacement{
|
||||||
|
issue: i.String(),
|
||||||
|
replacement: i.Replacement(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.ElementsMatch(t, test.expected, actualIssueStrs, "expected %s \nbut got %s", test.expected, actualIssues)
|
assert.ElementsMatch(t, test.expected, actualIssuesWithReplacements,
|
||||||
|
"expected %s \nbut got %s", test.expected, actualIssuesWithReplacements)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ type Range struct {
|
|||||||
|
|
||||||
type Replacement struct {
|
type Replacement struct {
|
||||||
NeedOnlyDelete bool // need to delete all lines of the issue without replacement with new lines
|
NeedOnlyDelete bool // need to delete all lines of the issue without replacement with new lines
|
||||||
NewLines []string // is NeedDelete is false it's the replacement lines
|
NewLines []string // if NeedDelete is false it's the replacement lines
|
||||||
Inline *InlineFix
|
Inline *InlineFix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ type ignoredRange struct {
|
|||||||
matchedIssueFromLinter map[string]bool
|
matchedIssueFromLinter map[string]bool
|
||||||
result.Range
|
result.Range
|
||||||
col int
|
col int
|
||||||
|
originalRange *ignoredRange // pre-expanded range (used to match nolintlint issues)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ignoredRange) doesMatch(issue *result.Issue) bool {
|
func (i *ignoredRange) doesMatch(issue *result.Issue) bool {
|
||||||
@ -163,7 +164,11 @@ func (p *Nolint) shouldPassIssue(i *result.Issue) (bool, error) {
|
|||||||
|
|
||||||
for _, ir := range fd.ignoredRanges {
|
for _, ir := range fd.ignoredRanges {
|
||||||
if ir.doesMatch(i) {
|
if ir.doesMatch(i) {
|
||||||
|
nolintDebugf("found ignored range for issue %v: %v", i, ir)
|
||||||
ir.matchedIssueFromLinter[i.FromLinter] = true
|
ir.matchedIssueFromLinter[i.FromLinter] = true
|
||||||
|
if ir.originalRange != nil {
|
||||||
|
ir.originalRange.matchedIssueFromLinter[i.FromLinter] = true
|
||||||
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,9 +204,14 @@ func (e *rangeExpander) Visit(node ast.Node) ast.Visitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expandedRange := *foundRange
|
expandedRange := *foundRange
|
||||||
|
// store the original unexpanded range for matching nolintlint issues
|
||||||
|
if expandedRange.originalRange == nil {
|
||||||
|
expandedRange.originalRange = foundRange
|
||||||
|
}
|
||||||
if expandedRange.To < nodeEndLine {
|
if expandedRange.To < nodeEndLine {
|
||||||
expandedRange.To = nodeEndLine
|
expandedRange.To = nodeEndLine
|
||||||
}
|
}
|
||||||
|
|
||||||
nolintDebugf("found range is %v for node %#v [%d;%d], expanded range is %v",
|
nolintDebugf("found range is %v for node %#v [%d;%d], expanded range is %v",
|
||||||
*foundRange, node, nodeStartLine, nodeEndLine, expandedRange)
|
*foundRange, node, nodeStartLine, nodeEndLine, expandedRange)
|
||||||
e.expandedRanges = append(e.expandedRanges, expandedRange)
|
e.expandedRanges = append(e.expandedRanges, expandedRange)
|
||||||
|
13
test/testdata/fix/in/nolintlint.go
vendored
Normal file
13
test/testdata/fix/in/nolintlint.go
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//args: -Enolintlint -Elll
|
||||||
|
//config: linters-settings.nolintlint.allow-leading-space=false
|
||||||
|
package p
|
||||||
|
|
||||||
|
func nolintlint() {
|
||||||
|
run() // nolint:bob // leading space should be dropped
|
||||||
|
run() // nolint:bob // leading spaces should be dropped
|
||||||
|
// note that the next lines will retain trailing whitespace when fixed
|
||||||
|
run() //nolint // nolint should be dropped
|
||||||
|
run() //nolint:lll // nolint should be dropped
|
||||||
|
run() //nolint:alice,lll,bob // enabled linter should be dropped
|
||||||
|
run() //nolint:alice,lll,bob,nolintlint // enabled linter should not be dropped when nolintlint is nolinted
|
||||||
|
}
|
13
test/testdata/fix/out/nolintlint.go
vendored
Normal file
13
test/testdata/fix/out/nolintlint.go
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//args: -Enolintlint -Elll
|
||||||
|
//config: linters-settings.nolintlint.allow-leading-space=false
|
||||||
|
package p
|
||||||
|
|
||||||
|
func nolintlint() {
|
||||||
|
run() //nolint:bob // leading space should be dropped
|
||||||
|
run() //nolint:bob // leading spaces should be dropped
|
||||||
|
// note that the next lines will retain trailing whitespace when fixed
|
||||||
|
run()
|
||||||
|
run()
|
||||||
|
run() //nolint:alice,bob // enabled linter should be dropped
|
||||||
|
run() //nolint:alice,lll,bob,nolintlint // enabled linter should not be dropped when nolintlint is nolinted
|
||||||
|
}
|
11
test/testdata/nolintlint.go
vendored
11
test/testdata/nolintlint.go
vendored
@ -1,7 +1,7 @@
|
|||||||
//args: -Enolintlint
|
//args: -Enolintlint -Emisspell
|
||||||
//config: linters-settings.nolintlint.require-explanation=true
|
//config: linters-settings.nolintlint.require-explanation=true
|
||||||
//config: linters-settings.nolintlint.require-specific=true
|
//config: linters-settings.nolintlint.require-specific=true
|
||||||
//config: linters-settings.nolintlint.allowing-leading-space=false
|
//config: linters-settings.nolintlint.allow-leading-space=false
|
||||||
package testdata
|
package testdata
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
@ -10,4 +10,11 @@ func Foo() {
|
|||||||
fmt.Println("not specific") //nolint // ERROR "directive `.*` should mention specific linter such as `//nolint:my-linter`"
|
fmt.Println("not specific") //nolint // ERROR "directive `.*` should mention specific linter such as `//nolint:my-linter`"
|
||||||
fmt.Println("not machine readable") // nolint // ERROR "directive `.*` should be written as `//nolint`"
|
fmt.Println("not machine readable") // nolint // ERROR "directive `.*` should be written as `//nolint`"
|
||||||
fmt.Println("extra spaces") // nolint:deadcode // because // ERROR "directive `.*` should not have more than one leading space"
|
fmt.Println("extra spaces") // nolint:deadcode // because // ERROR "directive `.*` should not have more than one leading space"
|
||||||
|
|
||||||
|
// test expanded range
|
||||||
|
//nolint:misspell // deliberate misspelling to trigger nolintlint
|
||||||
|
func() {
|
||||||
|
mispell := true
|
||||||
|
fmt.Println(mispell)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user