Skip to content

Commit dd67e40

Browse files
committed
Prepare for whitespace linter using the analysis package
The `whitespace` linter is rewritten to use `annalysis.Analyzer`. This PR will make use of the new code.
1 parent 5abc3f7 commit dd67e40

File tree

3 files changed

+45
-60
lines changed

3 files changed

+45
-60
lines changed

pkg/golinters/whitespace.go

Lines changed: 43 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package golinters
22

33
import (
44
"fmt"
5-
"go/token"
65
"sync"
76

87
"github.com/ultraware/whitespace"
@@ -14,8 +13,6 @@ import (
1413
"github.com/golangci/golangci-lint/pkg/result"
1514
)
1615

17-
const whitespaceName = "whitespace"
18-
1916
//nolint:dupl
2017
func NewWhitespace(settings *config.WhitespaceSettings) *goanalysis.Linter {
2118
var mu sync.Mutex
@@ -24,27 +21,58 @@ func NewWhitespace(settings *config.WhitespaceSettings) *goanalysis.Linter {
2421
var wsSettings whitespace.Settings
2522
if settings != nil {
2623
wsSettings = whitespace.Settings{
24+
Mode: whitespace.RunningModeGolangCI,
2725
MultiIf: settings.MultiIf,
2826
MultiFunc: settings.MultiFunc,
2927
}
3028
}
3129

32-
analyzer := &analysis.Analyzer{
33-
Name: whitespaceName,
34-
Doc: goanalysis.TheOnlyanalyzerDoc,
35-
Run: goanalysis.DummyRun,
36-
}
30+
whitespaceAnalyzer := whitespace.NewAnalyzer(&wsSettings)
3731

3832
return goanalysis.NewLinter(
39-
whitespaceName,
40-
"Tool for detection of leading and trailing whitespace",
41-
[]*analysis.Analyzer{analyzer},
33+
whitespaceAnalyzer.Name,
34+
whitespaceAnalyzer.Doc,
35+
[]*analysis.Analyzer{whitespaceAnalyzer},
4236
nil,
4337
).WithContextSetter(func(lintCtx *linter.Context) {
44-
analyzer.Run = func(pass *analysis.Pass) (any, error) {
45-
issues, err := runWhitespace(lintCtx, pass, wsSettings)
46-
if err != nil {
47-
return nil, err
38+
whitespaceAnalyzer.Run = func(pass *analysis.Pass) (any, error) {
39+
whitespaceIssues := whitespace.Run(pass, &wsSettings)
40+
issues := make([]goanalysis.Issue, len(whitespaceIssues))
41+
42+
for i, issue := range whitespaceIssues {
43+
report := &result.Issue{
44+
FromLinter: whitespaceAnalyzer.Name,
45+
Pos: pass.Fset.PositionFor(issue.Diagnostic, false),
46+
Text: issue.Message,
47+
}
48+
49+
switch issue.MessageType {
50+
case whitespace.MessageTypeRemove:
51+
report.LineRange = &result.Range{
52+
From: issue.LineNumber,
53+
To: issue.LineNumber,
54+
}
55+
56+
report.Replacement = &result.Replacement{
57+
NeedOnlyDelete: true,
58+
}
59+
60+
case whitespace.MessageTypeAdd:
61+
position := pass.Fset.PositionFor(issue.Diagnostic, false)
62+
bracketLine, err := lintCtx.LineCache.GetLine(position.Filename, position.Line)
63+
if err != nil {
64+
return nil, fmt.Errorf("failed to get line %s:%d: %w", position.Filename, position.Line, err)
65+
}
66+
67+
report.Replacement = &result.Replacement{
68+
NewLines: []string{bracketLine + "\n"},
69+
}
70+
71+
default:
72+
return nil, fmt.Errorf("unknown message type: %v", issue.MessageType)
73+
}
74+
75+
issues[i] = goanalysis.NewIssue(report, pass)
4876
}
4977

5078
if len(issues) == 0 {
@@ -61,48 +89,3 @@ func NewWhitespace(settings *config.WhitespaceSettings) *goanalysis.Linter {
6189
return resIssues
6290
}).WithLoadMode(goanalysis.LoadModeSyntax)
6391
}
64-
65-
func runWhitespace(lintCtx *linter.Context, pass *analysis.Pass, wsSettings whitespace.Settings) ([]goanalysis.Issue, error) {
66-
var messages []whitespace.Message
67-
for _, file := range pass.Files {
68-
messages = append(messages, whitespace.Run(file, pass.Fset, wsSettings)...)
69-
}
70-
71-
if len(messages) == 0 {
72-
return nil, nil
73-
}
74-
75-
issues := make([]goanalysis.Issue, len(messages))
76-
for k, i := range messages {
77-
issue := result.Issue{
78-
Pos: token.Position{
79-
Filename: i.Pos.Filename,
80-
Line: i.Pos.Line,
81-
},
82-
LineRange: &result.Range{From: i.Pos.Line, To: i.Pos.Line},
83-
Text: i.Message,
84-
FromLinter: whitespaceName,
85-
Replacement: &result.Replacement{},
86-
}
87-
88-
bracketLine, err := lintCtx.LineCache.GetLine(issue.Pos.Filename, issue.Pos.Line)
89-
if err != nil {
90-
return nil, fmt.Errorf("failed to get line %s:%d: %w", issue.Pos.Filename, issue.Pos.Line, err)
91-
}
92-
93-
switch i.Type {
94-
case whitespace.MessageTypeLeading:
95-
issue.LineRange.To++ // cover two lines by the issue: opening bracket "{" (issue.Pos.Line) and following empty line
96-
case whitespace.MessageTypeTrailing:
97-
issue.LineRange.From-- // cover two lines by the issue: closing bracket "}" (issue.Pos.Line) and preceding empty line
98-
issue.Pos.Line-- // set in sync with LineRange.From to not break fixer and other code features
99-
case whitespace.MessageTypeAddAfter:
100-
bracketLine += "\n"
101-
}
102-
issue.Replacement.NewLines = []string{bracketLine}
103-
104-
issues[k] = goanalysis.NewIssue(&issue, pass)
105-
}
106-
107-
return issues, nil
108-
}

test/testdata/fix/in/whitespace.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package p
55

66
import "fmt"
77

8+
//line yaccpar:1
89
func oneLeadingNewline() {
910

1011
fmt.Println("Hello world")

test/testdata/fix/out/whitespace.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package p
55

66
import "fmt"
77

8+
//line yaccpar:1
89
func oneLeadingNewline() {
910
fmt.Println("Hello world")
1011
}

0 commit comments

Comments
 (0)