github.com/vanstinator/golangci-lint@v0.0.0-20240223191551-cc572f00d9d1/pkg/golinters/mirror.go (about)

     1  package golinters
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/butuzov/mirror"
     7  	"golang.org/x/tools/go/analysis"
     8  
     9  	"github.com/vanstinator/golangci-lint/pkg/golinters/goanalysis"
    10  	"github.com/vanstinator/golangci-lint/pkg/lint/linter"
    11  	"github.com/vanstinator/golangci-lint/pkg/result"
    12  )
    13  
    14  func NewMirror() *goanalysis.Linter {
    15  	var (
    16  		mu     sync.Mutex
    17  		issues []goanalysis.Issue
    18  	)
    19  
    20  	a := mirror.NewAnalyzer()
    21  	a.Run = func(pass *analysis.Pass) (any, error) {
    22  		// mirror only lints test files if the `--with-tests` flag is passed,
    23  		// so we pass the `with-tests` flag as true to the analyzer before running it.
    24  		// This can be turned off by using the regular golangci-lint flags such as `--tests` or `--skip-files`
    25  		// or can be disabled per linter via exclude rules.
    26  		// (see https://github.com/vanstinator/golangci-lint/issues/2527#issuecomment-1023707262)
    27  		violations := mirror.Run(pass, true)
    28  
    29  		if len(violations) == 0 {
    30  			return nil, nil
    31  		}
    32  
    33  		for index := range violations {
    34  			i := violations[index].Issue(pass.Fset)
    35  
    36  			issue := result.Issue{
    37  				FromLinter: a.Name,
    38  				Text:       i.Message,
    39  				Pos:        i.Start,
    40  			}
    41  
    42  			if i.InlineFix != "" {
    43  				issue.Replacement = &result.Replacement{
    44  					Inline: &result.InlineFix{
    45  						StartCol:  i.Start.Column - 1,
    46  						Length:    len(i.Original),
    47  						NewString: i.InlineFix,
    48  					},
    49  				}
    50  			}
    51  
    52  			mu.Lock()
    53  			issues = append(issues, goanalysis.NewIssue(&issue, pass))
    54  			mu.Unlock()
    55  		}
    56  
    57  		return nil, nil
    58  	}
    59  
    60  	analyzer := goanalysis.NewLinter(
    61  		a.Name,
    62  		a.Doc,
    63  		[]*analysis.Analyzer{a},
    64  		nil,
    65  	).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
    66  		return issues
    67  	}).WithLoadMode(goanalysis.LoadModeTypesInfo)
    68  
    69  	return analyzer
    70  }