github.com/nozzle/golangci-lint@v1.49.0-nz3/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/golangci/golangci-lint/pkg/config" 11 "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" 12 "github.com/golangci/golangci-lint/pkg/golinters/nolintlint" 13 "github.com/golangci/golangci-lint/pkg/lint/linter" 14 "github.com/golangci/golangci-lint/pkg/result" 15 ) 16 17 const NoLintLintName = "nolintlint" 18 19 //nolint:dupl 20 func NewNoLintLint(settings *config.NoLintLintSettings) *goanalysis.Linter { 21 var mu sync.Mutex 22 var resIssues []goanalysis.Issue 23 24 analyzer := &analysis.Analyzer{ 25 Name: NoLintLintName, 26 Doc: goanalysis.TheOnlyanalyzerDoc, 27 Run: func(pass *analysis.Pass) (interface{}, error) { 28 issues, err := runNoLintLint(pass, settings) 29 if err != nil { 30 return nil, err 31 } 32 33 if len(issues) == 0 { 34 return nil, nil 35 } 36 37 mu.Lock() 38 resIssues = append(resIssues, issues...) 39 mu.Unlock() 40 41 return nil, nil 42 }, 43 } 44 45 return goanalysis.NewLinter( 46 NoLintLintName, 47 "Reports ill-formed or insufficient nolint directives", 48 []*analysis.Analyzer{analyzer}, 49 nil, 50 ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { 51 return resIssues 52 }).WithLoadMode(goanalysis.LoadModeSyntax) 53 } 54 55 func runNoLintLint(pass *analysis.Pass, settings *config.NoLintLintSettings) ([]goanalysis.Issue, error) { 56 var needs nolintlint.Needs 57 if settings.RequireExplanation { 58 needs |= nolintlint.NeedsExplanation 59 } 60 if settings.RequireSpecific { 61 needs |= nolintlint.NeedsSpecific 62 } 63 if !settings.AllowUnused { 64 needs |= nolintlint.NeedsUnused 65 } 66 67 lnt, err := nolintlint.NewLinter(needs, settings.AllowNoExplanation) 68 if err != nil { 69 return nil, err 70 } 71 72 nodes := make([]ast.Node, 0, len(pass.Files)) 73 for _, n := range pass.Files { 74 nodes = append(nodes, n) 75 } 76 77 lintIssues, err := lnt.Run(pass.Fset, nodes...) 78 if err != nil { 79 return nil, fmt.Errorf("linter failed to run: %s", err) 80 } 81 82 var issues []goanalysis.Issue 83 84 for _, i := range lintIssues { 85 expectNoLint := false 86 var expectedNolintLinter string 87 if ii, ok := i.(nolintlint.UnusedCandidate); ok { 88 expectedNolintLinter = ii.ExpectedLinter 89 expectNoLint = true 90 } 91 92 issue := &result.Issue{ 93 FromLinter: NoLintLintName, 94 Text: i.Details(), 95 Pos: i.Position(), 96 ExpectNoLint: expectNoLint, 97 ExpectedNoLintLinter: expectedNolintLinter, 98 Replacement: i.Replacement(), 99 } 100 101 issues = append(issues, goanalysis.NewIssue(issue, pass)) 102 } 103 104 return issues, nil 105 }