github.com/nozzle/golangci-lint@v1.49.0-nz3/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/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 preallocName = "prealloc"
    17  
    18  //nolint:dupl
    19  func NewPreAlloc(settings *config.PreallocSettings) *goanalysis.Linter {
    20  	var mu sync.Mutex
    21  	var resIssues []goanalysis.Issue
    22  
    23  	analyzer := &analysis.Analyzer{
    24  		Name: preallocName,
    25  		Doc:  goanalysis.TheOnlyanalyzerDoc,
    26  		Run: func(pass *analysis.Pass) (interface{}, error) {
    27  			issues := runPreAlloc(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  		preallocName,
    43  		"Finds slice declarations that could potentially be pre-allocated",
    44  		[]*analysis.Analyzer{analyzer},
    45  		nil,
    46  	).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
    47  		return resIssues
    48  	}).WithLoadMode(goanalysis.LoadModeSyntax)
    49  }
    50  
    51  func runPreAlloc(pass *analysis.Pass, settings *config.PreallocSettings) []goanalysis.Issue {
    52  	var issues []goanalysis.Issue
    53  
    54  	hints := pkg.Check(pass.Files, settings.Simple, settings.RangeLoops, settings.ForLoops)
    55  
    56  	for _, hint := range hints {
    57  		issues = append(issues, goanalysis.NewIssue(&result.Issue{
    58  			Pos:        pass.Fset.Position(hint.Pos),
    59  			Text:       fmt.Sprintf("Consider pre-allocating %s", formatCode(hint.DeclaredSliceName, nil)),
    60  			FromLinter: preallocName,
    61  		}, pass))
    62  	}
    63  
    64  	return issues
    65  }