github.com/elek/golangci-lint@v1.42.2-0.20211208090441-c05b7fcb3a9a/pkg/golinters/prealloc.go (about)

     1  package golinters
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  
     7  	"github.com/alexkohler/prealloc/pkg"
     8  	"golang.org/x/tools/go/analysis"
     9  
    10  	"github.com/elek/golangci-lint/pkg/golinters/goanalysis"
    11  	"github.com/elek/golangci-lint/pkg/lint/linter"
    12  	"github.com/elek/golangci-lint/pkg/result"
    13  )
    14  
    15  const preallocName = "prealloc"
    16  
    17  func NewPrealloc() *goanalysis.Linter {
    18  	var mu sync.Mutex
    19  	var resIssues []goanalysis.Issue
    20  
    21  	analyzer := &analysis.Analyzer{
    22  		Name: preallocName,
    23  		Doc:  goanalysis.TheOnlyanalyzerDoc,
    24  	}
    25  	return goanalysis.NewLinter(
    26  		preallocName,
    27  		"Finds slice declarations that could potentially be preallocated",
    28  		[]*analysis.Analyzer{analyzer},
    29  		nil,
    30  	).WithContextSetter(func(lintCtx *linter.Context) {
    31  		s := &lintCtx.Settings().Prealloc
    32  
    33  		analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
    34  			var res []goanalysis.Issue
    35  			hints := pkg.Check(pass.Files, s.Simple, s.RangeLoops, s.ForLoops)
    36  			for _, hint := range hints {
    37  				res = append(res, goanalysis.NewIssue(&result.Issue{
    38  					Pos:        pass.Fset.Position(hint.Pos),
    39  					Text:       fmt.Sprintf("Consider preallocating %s", formatCode(hint.DeclaredSliceName, lintCtx.Cfg)),
    40  					FromLinter: preallocName,
    41  				}, pass))
    42  			}
    43  
    44  			if len(res) == 0 {
    45  				return nil, nil
    46  			}
    47  
    48  			mu.Lock()
    49  			resIssues = append(resIssues, res...)
    50  			mu.Unlock()
    51  
    52  			return nil, nil
    53  		}
    54  	}).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
    55  		return resIssues
    56  	}).WithLoadMode(goanalysis.LoadModeSyntax)
    57  }