@@ -4,46 +4,31 @@ import (
4
4
"bufio"
5
5
"errors"
6
6
"fmt"
7
- "go/token "
7
+ "go/ast "
8
8
"os"
9
9
"strings"
10
- "sync"
11
10
"unicode/utf8"
12
11
13
12
"golang.org/x/tools/go/analysis"
14
13
15
14
"github.com/golangci/golangci-lint/pkg/config"
16
15
"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"
20
16
)
21
17
22
18
const linterName = "lll"
23
19
24
20
const goCommentDirectivePrefix = "//go:"
25
21
26
22
func New (settings * config.LllSettings ) * goanalysis.Linter {
27
- var mu sync.Mutex
28
- var resIssues []goanalysis.Issue
29
-
30
23
analyzer := & analysis.Analyzer {
31
24
Name : linterName ,
32
25
Doc : goanalysis .TheOnlyanalyzerDoc ,
33
26
Run : func (pass * analysis.Pass ) (any , error ) {
34
- issues , err := runLll (pass , settings )
27
+ err := runLll (pass , settings )
35
28
if err != nil {
36
29
return nil , err
37
30
}
38
31
39
- if len (issues ) == 0 {
40
- return nil , nil
41
- }
42
-
43
- mu .Lock ()
44
- resIssues = append (resIssues , issues ... )
45
- mu .Unlock ()
46
-
47
32
return nil , nil
48
33
},
49
34
}
@@ -53,40 +38,35 @@ func New(settings *config.LllSettings) *goanalysis.Linter {
53
38
"Reports long lines" ,
54
39
[]* analysis.Analyzer {analyzer },
55
40
nil ,
56
- ).WithIssuesReporter (func (* linter.Context ) []goanalysis.Issue {
57
- return resIssues
58
- }).WithLoadMode (goanalysis .LoadModeSyntax )
41
+ ).WithLoadMode (goanalysis .LoadModeSyntax )
59
42
}
60
43
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 {
64
45
spaces := strings .Repeat (" " , settings .TabWidth )
65
46
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 )
69
49
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
75
51
}
76
52
}
77
53
78
- return issues , nil
54
+ return nil
79
55
}
80
56
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 )
83
60
84
- f , err := os .Open (filename )
61
+ f , err := os .Open (position . Filename )
85
62
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 )
87
64
}
65
+
88
66
defer f .Close ()
89
67
68
+ ft := pass .Fset .File (file .Pos ())
69
+
90
70
lineNumber := 0
91
71
multiImportEnabled := false
92
72
@@ -116,42 +96,34 @@ func getLLLIssuesForFile(filename string, maxLineLen int, tabSpaces string) ([]r
116
96
117
97
lineLen := utf8 .RuneCountInString (line )
118
98
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 ),
126
103
})
127
104
}
128
105
}
129
106
130
107
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.
131
118
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 ),
150
122
})
151
123
} 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 )
153
125
}
154
126
}
155
127
156
- return res , nil
128
+ return nil
157
129
}
0 commit comments