Skip to content

Commit 6d29861

Browse files
authored
dev: processor optimizations (#5316)
1 parent c668d95 commit 6d29861

File tree

14 files changed

+340
-254
lines changed

14 files changed

+340
-254
lines changed

pkg/commands/run.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ func (c *runCommand) preRunE(_ *cobra.Command, args []string) error {
217217

218218
pkgLoader := lint.NewPackageLoader(c.log.Child(logutils.DebugKeyLoader), c.cfg, args, c.goenv, guard)
219219

220-
c.contextBuilder = lint.NewContextBuilder(c.cfg, pkgLoader, c.fileCache, pkgCache, guard)
220+
c.contextBuilder = lint.NewContextBuilder(c.cfg, pkgLoader, pkgCache, guard)
221221

222222
if err = initHashSalt(c.buildInfo.Version, c.cfg); err != nil {
223223
return fmt.Errorf("failed to init hash salt: %w", err)

pkg/golinters/misspell/misspell.go

+24-34
Original file line numberDiff line numberDiff line change
@@ -12,50 +12,38 @@ import (
1212

1313
"github.com/golangci/golangci-lint/pkg/config"
1414
"github.com/golangci/golangci-lint/pkg/goanalysis"
15-
"github.com/golangci/golangci-lint/pkg/lint/linter"
15+
"github.com/golangci/golangci-lint/pkg/golinters/internal"
1616
)
1717

1818
const linterName = "misspell"
1919

2020
func New(settings *config.MisspellSettings) *goanalysis.Linter {
21-
analyzer := &analysis.Analyzer{
22-
Name: linterName,
23-
Doc: goanalysis.TheOnlyanalyzerDoc,
24-
Run: goanalysis.DummyRun,
21+
replacer, err := createMisspellReplacer(settings)
22+
if err != nil {
23+
internal.LinterLogger.Fatalf("%s: %v", linterName, err)
2524
}
2625

27-
return goanalysis.NewLinter(
28-
linterName,
29-
"Finds commonly misspelled English words",
30-
[]*analysis.Analyzer{analyzer},
31-
nil,
32-
).WithContextSetter(func(lintCtx *linter.Context) {
33-
replacer, ruleErr := createMisspellReplacer(settings)
34-
35-
analyzer.Run = func(pass *analysis.Pass) (any, error) {
36-
if ruleErr != nil {
37-
return nil, ruleErr
38-
}
39-
40-
err := runMisspell(lintCtx, pass, replacer, settings.Mode)
41-
if err != nil {
42-
return nil, err
26+
a := &analysis.Analyzer{
27+
Name: linterName,
28+
Doc: "Finds commonly misspelled English words",
29+
Run: func(pass *analysis.Pass) (any, error) {
30+
for _, file := range pass.Files {
31+
err := runMisspellOnFile(pass, file, replacer, settings.Mode)
32+
if err != nil {
33+
return nil, err
34+
}
4335
}
4436

4537
return nil, nil
46-
}
47-
}).WithLoadMode(goanalysis.LoadModeSyntax)
48-
}
49-
50-
func runMisspell(lintCtx *linter.Context, pass *analysis.Pass, replacer *misspell.Replacer, mode string) error {
51-
for _, file := range pass.Files {
52-
err := runMisspellOnFile(lintCtx, pass, file, replacer, mode)
53-
if err != nil {
54-
return err
55-
}
38+
},
5639
}
5740

58-
return nil
41+
return goanalysis.NewLinter(
42+
a.Name,
43+
a.Doc,
44+
[]*analysis.Analyzer{a},
45+
nil,
46+
).WithLoadMode(goanalysis.LoadModeSyntax)
5947
}
6048

6149
func createMisspellReplacer(settings *config.MisspellSettings) (*misspell.Replacer, error) {
@@ -90,13 +78,15 @@ func createMisspellReplacer(settings *config.MisspellSettings) (*misspell.Replac
9078
return replacer, nil
9179
}
9280

93-
func runMisspellOnFile(lintCtx *linter.Context, pass *analysis.Pass, file *ast.File, replacer *misspell.Replacer, mode string) error {
81+
func runMisspellOnFile(pass *analysis.Pass, file *ast.File, replacer *misspell.Replacer, mode string) error {
9482
position, isGoFile := goanalysis.GetGoFilePosition(pass, file)
9583
if !isGoFile {
9684
return nil
9785
}
9886

99-
fileContent, err := lintCtx.FileCache.GetFileBytes(position.Filename)
87+
// Uses the non-adjusted file to work with cgo:
88+
// if we read the real file, the positions are wrong in some cases.
89+
fileContent, err := pass.ReadFile(pass.Fset.PositionFor(file.Pos(), false).Filename)
10090
if err != nil {
10191
return fmt.Errorf("can't get file %s contents: %w", position.Filename, err)
10292
}

pkg/golinters/misspell/testdata/misspell_cgo.go

+9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ package testdata
1313
import "C"
1414

1515
import (
16+
"fmt"
1617
"unsafe"
1718
)
1819

@@ -28,3 +29,11 @@ func Misspell() {
2829

2930
// the word langauge should be ignored here: it's set in config
3031
// the word Dialogue should be ignored here: it's set in config
32+
33+
func _() error {
34+
cs := C.CString("Hello from stdio\n")
35+
C.myprint(cs)
36+
C.free(unsafe.Pointer(cs))
37+
38+
return fmt.Errorf("an unknown error ocurred") // want "`ocurred` is a misspelling of `occurred`"
39+
}

pkg/lint/context.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"github.com/golangci/golangci-lint/internal/cache"
88
"github.com/golangci/golangci-lint/pkg/config"
99
"github.com/golangci/golangci-lint/pkg/exitcodes"
10-
"github.com/golangci/golangci-lint/pkg/fsutils"
1110
"github.com/golangci/golangci-lint/pkg/goanalysis/load"
1211
"github.com/golangci/golangci-lint/pkg/lint/linter"
1312
"github.com/golangci/golangci-lint/pkg/logutils"
@@ -18,19 +17,17 @@ type ContextBuilder struct {
1817

1918
pkgLoader *PackageLoader
2019

21-
fileCache *fsutils.FileCache
22-
pkgCache *cache.Cache
20+
pkgCache *cache.Cache
2321

2422
loadGuard *load.Guard
2523
}
2624

2725
func NewContextBuilder(cfg *config.Config, pkgLoader *PackageLoader,
28-
fileCache *fsutils.FileCache, pkgCache *cache.Cache, loadGuard *load.Guard,
26+
pkgCache *cache.Cache, loadGuard *load.Guard,
2927
) *ContextBuilder {
3028
return &ContextBuilder{
3129
cfg: cfg,
3230
pkgLoader: pkgLoader,
33-
fileCache: fileCache,
3431
pkgCache: pkgCache,
3532
loadGuard: loadGuard,
3633
}
@@ -55,7 +52,6 @@ func (cl *ContextBuilder) Build(ctx context.Context, log logutils.Log, linters [
5552

5653
Cfg: cl.cfg,
5754
Log: log,
58-
FileCache: cl.fileCache,
5955
PkgCache: cl.pkgCache,
6056
LoadGuard: cl.loadGuard,
6157
}

pkg/lint/linter/context.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77

88
"github.com/golangci/golangci-lint/internal/cache"
99
"github.com/golangci/golangci-lint/pkg/config"
10-
"github.com/golangci/golangci-lint/pkg/fsutils"
1110
"github.com/golangci/golangci-lint/pkg/goanalysis/load"
1211
"github.com/golangci/golangci-lint/pkg/logutils"
1312
)
@@ -20,9 +19,8 @@ type Context struct {
2019
// version for each of packages
2120
OriginalPackages []*packages.Package
2221

23-
Cfg *config.Config
24-
FileCache *fsutils.FileCache
25-
Log logutils.Log
22+
Cfg *config.Config
23+
Log logutils.Log
2624

2725
PkgCache *cache.Cache
2826
LoadGuard *load.Guard

pkg/lint/runner.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,19 @@ func NewRunner(log logutils.Log, cfg *config.Config, args []string, goenv *gouti
6868

6969
return &Runner{
7070
Processors: []processors.Processor{
71+
// Must be the first processor.
72+
processors.NewPathAbsoluter(log),
73+
7174
processors.NewCgo(goenv),
7275

73-
// Must go after Cgo.
76+
// Must be after Cgo.
7477
processors.NewFilenameUnadjuster(lintCtx.Packages, log.Child(logutils.DebugKeyFilenameUnadjuster)),
7578

76-
// Must go after FilenameUnadjuster.
79+
// Must be after FilenameUnadjuster.
7780
processors.NewInvalidIssue(log.Child(logutils.DebugKeyInvalidIssue)),
7881

7982
// Must be before diff, nolint and exclude autogenerated processor at least.
80-
processors.NewPathPrettifier(),
83+
processors.NewPathPrettifier(log),
8184
skipFilesProcessor,
8285
skipDirsProcessor, // must be after path prettifier
8386

@@ -88,13 +91,15 @@ func NewRunner(log logutils.Log, cfg *config.Config, args []string, goenv *gouti
8891

8992
processors.NewExclude(&cfg.Issues),
9093
processors.NewExcludeRules(log.Child(logutils.DebugKeyExcludeRules), files, &cfg.Issues),
94+
9195
processors.NewNolint(log.Child(logutils.DebugKeyNolint), dbManager, enabledLinters),
9296

9397
processors.NewUniqByLine(cfg),
9498
processors.NewDiff(&cfg.Issues),
9599
processors.NewMaxPerFileFromLinter(cfg),
96100
processors.NewMaxSameIssues(cfg.Issues.MaxSameIssues, log.Child(logutils.DebugKeyMaxSameIssues), cfg),
97101
processors.NewMaxFromLinter(cfg.Issues.MaxIssuesPerLinter, log.Child(logutils.DebugKeyMaxFromLinter), cfg),
102+
98103
processors.NewSourceCode(lineCache, log.Child(logutils.DebugKeySourceCode)),
99104
processors.NewPathShortener(),
100105
processors.NewSeverity(log.Child(logutils.DebugKeySeverityRules), files, &cfg.Severity),

pkg/logutils/logutils.go

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ const (
3636
DebugKeyLoader = "loader" // Debugs packages loading (including `go/packages` internal debugging).
3737
DebugKeyMaxFromLinter = "max_from_linter"
3838
DebugKeyMaxSameIssues = "max_same_issues"
39+
DebugKeyPathAbsoluter = "path_absoluter"
40+
DebugKeyPathPrettifier = "path_prettifier"
3941
DebugKeyPkgCache = "pkgcache"
4042
DebugKeyRunner = "runner"
4143
DebugKeySeverityRules = "severity_rules"

pkg/result/processors/cgo.go

+10-20
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package processors
22

33
import (
4-
"fmt"
54
"path/filepath"
65
"strings"
76

@@ -11,6 +10,10 @@ import (
1110

1211
var _ Processor = (*Cgo)(nil)
1312

13+
// Cgo some linters (e.g. gosec, deadcode) return incorrect filepaths for cgo issues,
14+
// also cgo files have strange issues looking like false positives.
15+
//
16+
// Require absolute filepath.
1417
type Cgo struct {
1518
goCacheDir string
1619
}
@@ -21,32 +24,19 @@ func NewCgo(goenv *goutil.Env) *Cgo {
2124
}
2225
}
2326

24-
func (Cgo) Name() string {
27+
func (*Cgo) Name() string {
2528
return "cgo"
2629
}
2730

28-
func (p Cgo) Process(issues []result.Issue) ([]result.Issue, error) {
31+
func (p *Cgo) Process(issues []result.Issue) ([]result.Issue, error) {
2932
return filterIssuesErr(issues, p.shouldPassIssue)
3033
}
3134

32-
func (Cgo) Finish() {}
35+
func (*Cgo) Finish() {}
3336

34-
func (p Cgo) shouldPassIssue(issue *result.Issue) (bool, error) {
35-
// some linters (e.g. gosec, deadcode) return incorrect filepaths for cgo issues,
36-
// also cgo files have strange issues looking like false positives.
37-
38-
// cache dir contains all preprocessed files including cgo files
39-
40-
issueFilePath := issue.FilePath()
41-
if !filepath.IsAbs(issue.FilePath()) {
42-
absPath, err := filepath.Abs(issue.FilePath())
43-
if err != nil {
44-
return false, fmt.Errorf("failed to build abs path for %q: %w", issue.FilePath(), err)
45-
}
46-
issueFilePath = absPath
47-
}
48-
49-
if p.goCacheDir != "" && strings.HasPrefix(issueFilePath, p.goCacheDir) {
37+
func (p *Cgo) shouldPassIssue(issue *result.Issue) (bool, error) {
38+
// [p.goCacheDir] contains all preprocessed files including cgo files.
39+
if p.goCacheDir != "" && strings.HasPrefix(issue.FilePath(), p.goCacheDir) {
5040
return false, nil
5141
}
5242

pkg/result/processors/diff.go

+14-9
Original file line numberDiff line numberDiff line change
@@ -36,32 +36,36 @@ func NewDiff(cfg *config.Issues) *Diff {
3636
}
3737
}
3838

39-
func (Diff) Name() string {
39+
func (*Diff) Name() string {
4040
return "diff"
4141
}
4242

43-
func (p Diff) Process(issues []result.Issue) ([]result.Issue, error) {
44-
if !p.onlyNew && p.fromRev == "" && p.patchFilePath == "" && p.patch == "" { // no need to work
43+
func (p *Diff) Process(issues []result.Issue) ([]result.Issue, error) {
44+
if !p.onlyNew && p.fromRev == "" && p.patchFilePath == "" && p.patch == "" {
4545
return issues, nil
4646
}
4747

4848
var patchReader io.Reader
49-
if p.patchFilePath != "" {
49+
switch {
50+
case p.patchFilePath != "":
5051
patch, err := os.ReadFile(p.patchFilePath)
5152
if err != nil {
5253
return nil, fmt.Errorf("can't read from patch file %s: %w", p.patchFilePath, err)
5354
}
55+
5456
patchReader = bytes.NewReader(patch)
55-
} else if p.patch != "" {
57+
58+
case p.patch != "":
5659
patchReader = strings.NewReader(p.patch)
5760
}
5861

59-
c := revgrep.Checker{
62+
checker := revgrep.Checker{
6063
Patch: patchReader,
6164
RevisionFrom: p.fromRev,
6265
WholeFiles: p.wholeFiles,
6366
}
64-
if err := c.Prepare(context.Background()); err != nil {
67+
68+
if err := checker.Prepare(context.Background()); err != nil {
6569
return nil, fmt.Errorf("can't prepare diff by revgrep: %w", err)
6670
}
6771

@@ -71,15 +75,16 @@ func (p Diff) Process(issues []result.Issue) ([]result.Issue, error) {
7175
return issue
7276
}
7377

74-
hunkPos, isNew := c.IsNewIssue(issue)
78+
hunkPos, isNew := checker.IsNewIssue(issue)
7579
if !isNew {
7680
return nil
7781
}
7882

7983
newIssue := *issue
8084
newIssue.HunkPos = hunkPos
85+
8186
return &newIssue
8287
}), nil
8388
}
8489

85-
func (Diff) Finish() {}
90+
func (*Diff) Finish() {}

0 commit comments

Comments
 (0)