github.com/nozzle/golangci-lint@v1.49.0-nz3/pkg/golinters/nestif.go (about)

     1  package golinters
     2  
     3  import (
     4  	"sort"
     5  	"sync"
     6  
     7  	"github.com/nakabonne/nestif"
     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/lint/linter"
    13  	"github.com/golangci/golangci-lint/pkg/result"
    14  )
    15  
    16  const nestifName = "nestif"
    17  
    18  //nolint:dupl
    19  func NewNestif(settings *config.NestifSettings) *goanalysis.Linter {
    20  	var mu sync.Mutex
    21  	var resIssues []goanalysis.Issue
    22  
    23  	analyzer := &analysis.Analyzer{
    24  		Name: goanalysis.TheOnlyAnalyzerName,
    25  		Doc:  goanalysis.TheOnlyanalyzerDoc,
    26  		Run: func(pass *analysis.Pass) (interface{}, error) {
    27  			issues := runNestIf(pass, settings)
    28  
    29  			if len(issues) == 0 {
    30  				return nil, nil
    31  			}
    32  
    33  			mu.Lock()
    34  			resIssues = append(resIssues, issues...)
    35  			mu.Unlock()
    36  
    37  			return nil, nil
    38  		},
    39  	}
    40  
    41  	return goanalysis.NewLinter(
    42  		nestifName,
    43  		"Reports deeply nested if statements",
    44  		[]*analysis.Analyzer{analyzer},
    45  		nil,
    46  	).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
    47  		return resIssues
    48  	}).WithLoadMode(goanalysis.LoadModeSyntax)
    49  }
    50  
    51  func runNestIf(pass *analysis.Pass, settings *config.NestifSettings) []goanalysis.Issue {
    52  	checker := &nestif.Checker{
    53  		MinComplexity: settings.MinComplexity,
    54  	}
    55  
    56  	var lintIssues []nestif.Issue
    57  	for _, f := range pass.Files {
    58  		lintIssues = append(lintIssues, checker.Check(f, pass.Fset)...)
    59  	}
    60  
    61  	if len(lintIssues) == 0 {
    62  		return nil
    63  	}
    64  
    65  	sort.SliceStable(lintIssues, func(i, j int) bool {
    66  		return lintIssues[i].Complexity > lintIssues[j].Complexity
    67  	})
    68  
    69  	issues := make([]goanalysis.Issue, 0, len(lintIssues))
    70  	for _, i := range lintIssues {
    71  		issues = append(issues, goanalysis.NewIssue(&result.Issue{
    72  			Pos:        i.Pos,
    73  			Text:       i.Message,
    74  			FromLinter: nestifName,
    75  		}, pass))
    76  	}
    77  
    78  	return issues
    79  }