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

     1  package golinters
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  
     7  	lintAPI "github.com/golangci/lint-1"
     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 golintName = "golint"
    17  
    18  //nolint:dupl
    19  func NewGolint(settings *config.GoLintSettings) *goanalysis.Linter {
    20  	var mu sync.Mutex
    21  	var resIssues []goanalysis.Issue
    22  
    23  	analyzer := &analysis.Analyzer{
    24  		Name: golintName,
    25  		Doc:  goanalysis.TheOnlyanalyzerDoc,
    26  		Run: func(pass *analysis.Pass) (interface{}, error) {
    27  			issues, err := runGoLint(pass, settings)
    28  			if err != nil {
    29  				return nil, err
    30  			}
    31  
    32  			if len(issues) == 0 {
    33  				return nil, nil
    34  			}
    35  
    36  			mu.Lock()
    37  			resIssues = append(resIssues, issues...)
    38  			mu.Unlock()
    39  
    40  			return nil, nil
    41  		},
    42  	}
    43  
    44  	return goanalysis.NewLinter(
    45  		golintName,
    46  		"Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes",
    47  		[]*analysis.Analyzer{analyzer},
    48  		nil,
    49  	).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
    50  		return resIssues
    51  	}).WithLoadMode(goanalysis.LoadModeTypesInfo)
    52  }
    53  
    54  func runGoLint(pass *analysis.Pass, settings *config.GoLintSettings) ([]goanalysis.Issue, error) {
    55  	l := new(lintAPI.Linter)
    56  
    57  	ps, err := l.LintPkg(pass.Files, pass.Fset, pass.Pkg, pass.TypesInfo)
    58  	if err != nil {
    59  		return nil, fmt.Errorf("can't lint %d files: %s", len(pass.Files), err)
    60  	}
    61  
    62  	if len(ps) == 0 {
    63  		return nil, nil
    64  	}
    65  
    66  	lintIssues := make([]*result.Issue, 0, len(ps)) // This is worst case
    67  	for idx := range ps {
    68  		if ps[idx].Confidence >= settings.MinConfidence {
    69  			lintIssues = append(lintIssues, &result.Issue{
    70  				Pos:        ps[idx].Position,
    71  				Text:       ps[idx].Text,
    72  				FromLinter: golintName,
    73  			})
    74  			// TODO: use p.Link and p.Category
    75  		}
    76  	}
    77  
    78  	issues := make([]goanalysis.Issue, 0, len(lintIssues))
    79  	for _, issue := range lintIssues {
    80  		issues = append(issues, goanalysis.NewIssue(issue, pass))
    81  	}
    82  
    83  	return issues, nil
    84  }