Skip to content

Commit 3c47cda

Browse files
committed
chore: migrate LLL
1 parent c4ba66d commit 3c47cda

File tree

5 files changed

+70
-65
lines changed

5 files changed

+70
-65
lines changed

pkg/golinters/lll/lll.go

Lines changed: 35 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,46 +4,31 @@ import (
44
"bufio"
55
"errors"
66
"fmt"
7-
"go/token"
7+
"go/ast"
88
"os"
99
"strings"
10-
"sync"
1110
"unicode/utf8"
1211

1312
"golang.org/x/tools/go/analysis"
1413

1514
"github.com/golangci/golangci-lint/pkg/config"
1615
"github.com/golangci/golangci-lint/pkg/goanalysis"
17-
"github.com/golangci/golangci-lint/pkg/golinters/internal"
18-
"github.com/golangci/golangci-lint/pkg/lint/linter"
19-
"github.com/golangci/golangci-lint/pkg/result"
2016
)
2117

2218
const linterName = "lll"
2319

2420
const goCommentDirectivePrefix = "//go:"
2521

2622
func New(settings *config.LllSettings) *goanalysis.Linter {
27-
var mu sync.Mutex
28-
var resIssues []goanalysis.Issue
29-
3023
analyzer := &analysis.Analyzer{
3124
Name: linterName,
3225
Doc: goanalysis.TheOnlyanalyzerDoc,
3326
Run: func(pass *analysis.Pass) (any, error) {
34-
issues, err := runLll(pass, settings)
27+
err := runLll(pass, settings)
3528
if err != nil {
3629
return nil, err
3730
}
3831

39-
if len(issues) == 0 {
40-
return nil, nil
41-
}
42-
43-
mu.Lock()
44-
resIssues = append(resIssues, issues...)
45-
mu.Unlock()
46-
4732
return nil, nil
4833
},
4934
}
@@ -53,40 +38,35 @@ func New(settings *config.LllSettings) *goanalysis.Linter {
5338
"Reports long lines",
5439
[]*analysis.Analyzer{analyzer},
5540
nil,
56-
).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
57-
return resIssues
58-
}).WithLoadMode(goanalysis.LoadModeSyntax)
41+
).WithLoadMode(goanalysis.LoadModeSyntax)
5942
}
6043

61-
func runLll(pass *analysis.Pass, settings *config.LllSettings) ([]goanalysis.Issue, error) {
62-
fileNames := internal.GetFileNames(pass)
63-
44+
func runLll(pass *analysis.Pass, settings *config.LllSettings) error {
6445
spaces := strings.Repeat(" ", settings.TabWidth)
6546

66-
var issues []goanalysis.Issue
67-
for _, f := range fileNames {
68-
lintIssues, err := getLLLIssuesForFile(f, settings.LineLength, spaces)
47+
for _, file := range pass.Files {
48+
err := getLLLIssuesForFile(pass, file, settings.LineLength, spaces)
6949
if err != nil {
70-
return nil, err
71-
}
72-
73-
for i := range lintIssues {
74-
issues = append(issues, goanalysis.NewIssue(&lintIssues[i], pass))
50+
return err
7551
}
7652
}
7753

78-
return issues, nil
54+
return nil
7955
}
8056

81-
func getLLLIssuesForFile(filename string, maxLineLen int, tabSpaces string) ([]result.Issue, error) {
82-
var res []result.Issue
57+
func getLLLIssuesForFile(pass *analysis.Pass, file *ast.File, maxLineLen int, tabSpaces string) error {
58+
position := goanalysis.GetFilePosition(pass, file)
59+
nonAdjPosition := pass.Fset.PositionFor(file.Pos(), false)
8360

84-
f, err := os.Open(filename)
61+
f, err := os.Open(position.Filename)
8562
if err != nil {
86-
return nil, fmt.Errorf("can't open file %s: %w", filename, err)
63+
return fmt.Errorf("can't open file %s: %w", position.Filename, err)
8764
}
65+
8866
defer f.Close()
8967

68+
ft := pass.Fset.File(file.Pos())
69+
9070
lineNumber := 0
9171
multiImportEnabled := false
9272

@@ -116,42 +96,34 @@ func getLLLIssuesForFile(filename string, maxLineLen int, tabSpaces string) ([]r
11696

11797
lineLen := utf8.RuneCountInString(line)
11898
if lineLen > maxLineLen {
119-
res = append(res, result.Issue{
120-
Pos: token.Position{
121-
Filename: filename,
122-
Line: lineNumber,
123-
},
124-
Text: fmt.Sprintf("the line is %d characters long, which exceeds the maximum of %d characters.", lineLen, maxLineLen),
125-
FromLinter: linterName,
99+
pass.Report(analysis.Diagnostic{
100+
Pos: ft.LineStart(goanalysis.AdjustPos(lineNumber, nonAdjPosition.Line, position.Line)),
101+
Message: fmt.Sprintf("The line is %d characters long, which exceeds the maximum of %d characters.",
102+
lineLen, maxLineLen),
126103
})
127104
}
128105
}
129106

130107
if err := scanner.Err(); err != nil {
108+
// scanner.Scan() might fail if the line is longer than bufio.MaxScanTokenSize
109+
// In the case where the specified maxLineLen is smaller than bufio.MaxScanTokenSize
110+
// we can return this line as a long line instead of returning an error.
111+
// The reason for this change is that this case might happen with autogenerated files
112+
// The go-bindata tool for instance might generate a file with a very long line.
113+
// In this case, as it's an auto generated file, the warning returned by lll will
114+
// be ignored.
115+
// But if we return a linter error here, and this error happens for an autogenerated
116+
// file the error will be discarded (fine), but all the subsequent errors for lll will
117+
// be discarded for other files, and we'll miss legit error.
131118
if errors.Is(err, bufio.ErrTooLong) && maxLineLen < bufio.MaxScanTokenSize {
132-
// scanner.Scan() might fail if the line is longer than bufio.MaxScanTokenSize
133-
// In the case where the specified maxLineLen is smaller than bufio.MaxScanTokenSize
134-
// we can return this line as a long line instead of returning an error.
135-
// The reason for this change is that this case might happen with autogenerated files
136-
// The go-bindata tool for instance might generate a file with a very long line.
137-
// In this case, as it's an auto generated file, the warning returned by lll will
138-
// be ignored.
139-
// But if we return a linter error here, and this error happens for an autogenerated
140-
// file the error will be discarded (fine), but all the subsequent errors for lll will
141-
// be discarded for other files, and we'll miss legit error.
142-
res = append(res, result.Issue{
143-
Pos: token.Position{
144-
Filename: filename,
145-
Line: lineNumber,
146-
Column: 1,
147-
},
148-
Text: fmt.Sprintf("line is more than %d characters", bufio.MaxScanTokenSize),
149-
FromLinter: linterName,
119+
pass.Report(analysis.Diagnostic{
120+
Pos: ft.LineStart(goanalysis.AdjustPos(lineNumber, nonAdjPosition.Line, position.Line)),
121+
Message: fmt.Sprintf("line is more than %d characters", bufio.MaxScanTokenSize),
150122
})
151123
} else {
152-
return nil, fmt.Errorf("can't scan file %s: %w", filename, err)
124+
return fmt.Errorf("can't scan file %s: %w", position.Filename, err)
153125
}
154126
}
155127

156-
return res, nil
128+
return nil
157129
}

pkg/golinters/lll/testdata/lll.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import (
77
)
88

99
func Lll() {
10-
// In my experience, long lines are the lines with comments, not the code. So this is a long comment // want "line is 137 characters"
10+
// want +1 "line is 141 characters"
11+
// In my experience, long lines are the lines with comments, not the code. So this is a long comment, a very long comment, yes very long.
1112
}
1213

1314
//go:generate mockgen -source lll.go -destination a_verylong_generate_mock_my_lll_interface.go --package testdata -self_package github.com/golangci/golangci-lint/test/testdata

pkg/golinters/lll/testdata/lll_max_scan_token_size.go

Lines changed: 6 additions & 0 deletions
Large diffs are not rendered by default.

pkg/golinters/lll/testdata/lll_max_scan_token_size_cgo.go

Lines changed: 26 additions & 0 deletions
Large diffs are not rendered by default.

test/run_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ func TestLineDirective(t *testing.T) {
216216
},
217217
configPath: "testdata/linedirective/lll.yml",
218218
targetPath: "linedirective",
219-
expected: "the line is 57 characters long, which exceeds the maximum of 50 characters. (lll)",
219+
expected: "The line is 57 characters long, which exceeds the maximum of 50 characters. (lll)",
220220
},
221221
{
222222
desc: "misspell",

0 commit comments

Comments
 (0)