github.com/elek/golangci-lint@v1.42.2-0.20211208090441-c05b7fcb3a9a/pkg/golinters/maligned.go (about) 1 package golinters 2 3 import ( 4 "fmt" 5 "sync" 6 7 malignedAPI "github.com/golangci/maligned" 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 func NewMaligned() *goanalysis.Linter { 16 const linterName = "maligned" 17 var mu sync.Mutex 18 var res []goanalysis.Issue 19 analyzer := &analysis.Analyzer{ 20 Name: linterName, 21 Doc: goanalysis.TheOnlyanalyzerDoc, 22 } 23 return goanalysis.NewLinter( 24 linterName, 25 "Tool to detect Go structs that would take less memory if their fields were sorted", 26 []*analysis.Analyzer{analyzer}, 27 nil, 28 ).WithContextSetter(func(lintCtx *linter.Context) { 29 analyzer.Run = func(pass *analysis.Pass) (interface{}, error) { 30 prog := goanalysis.MakeFakeLoaderProgram(pass) 31 32 malignedIssues := malignedAPI.Run(prog) 33 if len(malignedIssues) == 0 { 34 return nil, nil 35 } 36 37 issues := make([]goanalysis.Issue, 0, len(malignedIssues)) 38 for _, i := range malignedIssues { 39 text := fmt.Sprintf("struct of size %d bytes could be of size %d bytes", i.OldSize, i.NewSize) 40 if lintCtx.Settings().Maligned.SuggestNewOrder { 41 text += fmt.Sprintf(":\n%s", formatCodeBlock(i.NewStructDef, lintCtx.Cfg)) 42 } 43 issues = append(issues, goanalysis.NewIssue(&result.Issue{ 44 Pos: i.Pos, 45 Text: text, 46 FromLinter: linterName, 47 }, pass)) 48 } 49 50 mu.Lock() 51 res = append(res, issues...) 52 mu.Unlock() 53 return nil, nil 54 } 55 }).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { 56 return res 57 }).WithLoadMode(goanalysis.LoadModeTypesInfo) 58 }