@@ -46,7 +46,7 @@ func (i *ignoredRange) doesMatch(issue *result.Issue) bool {
46
46
47
47
// handle possible unused nolint directives
48
48
// nolintlint generates potential issues for every nolint directive and they are filtered out here
49
- if issue .FromLinter == golinters .NolintlintName && issue .ExpectNoLint {
49
+ if issue .FromLinter == golinters .NolintlintName && issue .ExpectNoLint {
50
50
if issue .ExpectedNoLintLinter != "" {
51
51
return i .matchedIssueFromLinter [issue .ExpectedNoLintLinter ]
52
52
}
@@ -123,7 +123,7 @@ func (p *Nolint) getOrCreateFileData(i *result.Issue) (*fileData, error) {
123
123
}
124
124
125
125
func (p * Nolint ) buildIgnoredRangesForFile (f * ast.File , fset * token.FileSet , filePath string ) []ignoredRange {
126
- inlineRanges := p .extractFileCommentsInlineRanges (fset , f .Comments ... )
126
+ inlineRanges := p .extractFileCommentsRanges (fset , f .Comments ... )
127
127
nolintDebugf ("file %s: inline nolint ranges are %+v" , filePath , inlineRanges )
128
128
129
129
if len (inlineRanges ) == 0 {
@@ -218,20 +218,106 @@ func (e *rangeExpander) Visit(node ast.Node) ast.Visitor {
218
218
return e
219
219
}
220
220
221
- func (p * Nolint ) extractFileCommentsInlineRanges (fset * token.FileSet , comments ... * ast.CommentGroup ) []ignoredRange {
221
+ func (p * Nolint ) extractFileCommentsRanges (fset * token.FileSet , comments ... * ast.CommentGroup ) []ignoredRange {
222
222
var ret []ignoredRange
223
+ ignoredRangeMap := map [string ]* ignoredRange {}
223
224
for _ , g := range comments {
224
225
for _ , c := range g .List {
225
- ir := p .extractInlineRangeFromComment (c .Text , g , fset )
226
+ ignoredRangeMap = p .extractRangeBeginFromComment (c .Text , g , fset , ignoredRangeMap )
227
+
228
+ var ir * ignoredRange
229
+ ignoredRangeMap , ir = p .extractRangeEndFromComment (c .Text , g , fset , ignoredRangeMap )
230
+ if ir != nil {
231
+ ret = append (ret , * ir )
232
+ }
233
+
234
+ ir = p .extractInlineRangeFromComment (c .Text , g , fset )
226
235
if ir != nil {
227
236
ret = append (ret , * ir )
228
237
}
229
238
}
230
239
}
231
240
241
+ for _ , v := range ignoredRangeMap {
242
+ ret = append (ret , * v )
243
+ }
244
+
232
245
return ret
233
246
}
234
247
248
+ func (p * Nolint ) extractRangeBeginFromComment (
249
+ text string ,
250
+ g ast.Node ,
251
+ fset * token.FileSet ,
252
+ ignoredRangeMap map [string ]* ignoredRange ,
253
+ ) map [string ]* ignoredRange {
254
+ text = strings .TrimLeft (text , "/ " )
255
+ if strings .HasPrefix (text , "nolint-begin:" ) {
256
+ linterItems := strings .Split (strings .TrimPrefix (text , "nolint-begin:" ), "," )
257
+ for _ , l := range linterItems {
258
+ l = strings .TrimSpace (l )
259
+ if l == "" {
260
+ continue
261
+ }
262
+ _ , ok := ignoredRangeMap [l ]
263
+ if ok {
264
+ // If there are two consecutive nolint-begins, the first nolint-begin is valid.
265
+ continue
266
+ }
267
+ ignoredRangeMap [l ] = & ignoredRange {
268
+ Range : result.Range {
269
+ From : fset .Position (g .Pos ()).Line ,
270
+ To : fset .File (g .End ()).LineCount (),
271
+ },
272
+ linters : []string {l },
273
+ matchedIssueFromLinter : make (map [string ]bool ),
274
+ }
275
+ }
276
+ return ignoredRangeMap
277
+ }
278
+
279
+ if strings .HasPrefix (text , "nolint-begin" ) {
280
+ key := ""
281
+ ignoredRangeMap [key ] = & ignoredRange {
282
+ Range : result.Range {
283
+ From : fset .Position (g .Pos ()).Line ,
284
+ To : fset .File (g .End ()).LineCount (),
285
+ },
286
+ linters : nil ,
287
+ matchedIssueFromLinter : make (map [string ]bool ),
288
+ }
289
+ }
290
+ return ignoredRangeMap
291
+ }
292
+
293
+ func (p * Nolint ) extractRangeEndFromComment (
294
+ text string ,
295
+ g ast.Node ,
296
+ fset * token.FileSet ,
297
+ ignoredRangeMap map [string ]* ignoredRange ,
298
+ ) (map [string ]* ignoredRange , * ignoredRange ) {
299
+ text = strings .TrimLeft (text , "/ " )
300
+ if strings .HasPrefix (text , "nolint-end" ) {
301
+ var linters []string
302
+ if strings .HasPrefix (text , "nolint-end:" ) {
303
+ linters = strings .Split (strings .TrimPrefix (text , "nolint-end:" ), "," )
304
+ } else {
305
+ linters = []string {"" }
306
+ }
307
+
308
+ for _ , linter := range linters {
309
+ linter = strings .TrimSpace (linter )
310
+ ir := ignoredRangeMap [linter ]
311
+ if ir != nil {
312
+ ir .Range .To = fset .Position (g .End ()).Line
313
+ delete (ignoredRangeMap , linter )
314
+ return ignoredRangeMap , ir
315
+ }
316
+ }
317
+ }
318
+ return ignoredRangeMap , nil
319
+ }
320
+
235
321
func (p * Nolint ) extractInlineRangeFromComment (text string , g ast.Node , fset * token.FileSet ) * ignoredRange {
236
322
text = strings .TrimLeft (text , "/ " )
237
323
if ! strings .HasPrefix (text , "nolint" ) {
@@ -251,13 +337,18 @@ func (p *Nolint) extractInlineRangeFromComment(text string, g ast.Node, fset *to
251
337
}
252
338
}
253
339
254
- if ! strings .HasPrefix (text , "nolint:" ) {
340
+ text = strings .Split (text , "//" )[0 ] // allow another comment after this comment
341
+ text = strings .TrimSpace (text )
342
+ if text == "nolint" {
255
343
return buildRange (nil ) // ignore all linters
256
344
}
257
345
346
+ if ! strings .HasPrefix (text , "nolint:" ) {
347
+ return nil
348
+ }
349
+
258
350
// ignore specific linters
259
351
var linters []string
260
- text = strings .Split (text , "//" )[0 ] // allow another comment after this comment
261
352
linterItems := strings .Split (strings .TrimPrefix (text , "nolint:" ), "," )
262
353
for _ , linter := range linterItems {
263
354
linterName := strings .ToLower (strings .TrimSpace (linter ))
0 commit comments