github.com/elek/golangci-lint@v1.42.2-0.20211208090441-c05b7fcb3a9a/pkg/golinters/nolintlint.go (about) 1 package golinters 2 3 import ( 4 "fmt" 5 "go/ast" 6 "sync" 7 8 "golang.org/x/tools/go/analysis" 9 10 "github.com/elek/golangci-lint/pkg/golinters/goanalysis" 11 "github.com/elek/golangci-lint/pkg/golinters/nolintlint" 12 "github.com/elek/golangci-lint/pkg/lint/linter" 13 "github.com/elek/golangci-lint/pkg/result" 14 ) 15 16 const NolintlintName = "nolintlint" 17 18 func NewNoLintLint() *goanalysis.Linter { 19 var mu sync.Mutex 20 var resIssues []goanalysis.Issue 21 22 analyzer := &analysis.Analyzer{ 23 Name: NolintlintName, 24 Doc: goanalysis.TheOnlyanalyzerDoc, 25 } 26 return goanalysis.NewLinter( 27 NolintlintName, 28 "Reports ill-formed or insufficient nolint directives", 29 []*analysis.Analyzer{analyzer}, 30 nil, 31 ).WithContextSetter(func(lintCtx *linter.Context) { 32 analyzer.Run = func(pass *analysis.Pass) (interface{}, error) { 33 var needs nolintlint.Needs 34 settings := lintCtx.Settings().NoLintLint 35 if settings.RequireExplanation { 36 needs |= nolintlint.NeedsExplanation 37 } 38 if !settings.AllowLeadingSpace { 39 needs |= nolintlint.NeedsMachineOnly 40 } 41 if settings.RequireSpecific { 42 needs |= nolintlint.NeedsSpecific 43 } 44 if !settings.AllowUnused { 45 needs |= nolintlint.NeedsUnused 46 } 47 48 lnt, err := nolintlint.NewLinter(needs, settings.AllowNoExplanation) 49 if err != nil { 50 return nil, err 51 } 52 53 nodes := make([]ast.Node, 0, len(pass.Files)) 54 for _, n := range pass.Files { 55 nodes = append(nodes, n) 56 } 57 issues, err := lnt.Run(pass.Fset, nodes...) 58 if err != nil { 59 return nil, fmt.Errorf("linter failed to run: %s", err) 60 } 61 var res []goanalysis.Issue 62 for _, i := range issues { 63 expectNoLint := false 64 var expectedNolintLinter string 65 if ii, ok := i.(nolintlint.UnusedCandidate); ok { 66 expectedNolintLinter = ii.ExpectedLinter 67 expectNoLint = true 68 } 69 issue := &result.Issue{ 70 FromLinter: NolintlintName, 71 Text: i.Details(), 72 Pos: i.Position(), 73 ExpectNoLint: expectNoLint, 74 ExpectedNoLintLinter: expectedNolintLinter, 75 Replacement: i.Replacement(), 76 } 77 res = append(res, goanalysis.NewIssue(issue, pass)) 78 } 79 80 if len(res) == 0 { 81 return nil, nil 82 } 83 84 mu.Lock() 85 resIssues = append(resIssues, res...) 86 mu.Unlock() 87 88 return nil, nil 89 } 90 }).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { 91 return resIssues 92 }).WithLoadMode(goanalysis.LoadModeSyntax) 93 }