@@ -75,6 +75,7 @@ pub struct IgnoreDirective {
75
75
pub span : Span ,
76
76
pub codes : Vec < String > ,
77
77
pub used_codes : HashMap < String , bool > ,
78
+ pub is_global : bool ,
78
79
}
79
80
80
81
impl IgnoreDirective {
@@ -84,7 +85,10 @@ impl IgnoreDirective {
84
85
& mut self ,
85
86
diagnostic : & LintDiagnostic ,
86
87
) -> bool {
87
- if self . position . line != diagnostic. range . start . line - 1 {
88
+ // `is_global` means that diagnostic is ignored in whole file.
89
+ if self . is_global {
90
+ // pass
91
+ } else if self . position . line != diagnostic. range . start . line - 1 {
88
92
return false ;
89
93
}
90
94
@@ -234,28 +238,6 @@ impl Linter {
234
238
Ok ( diagnostics)
235
239
}
236
240
237
- fn has_ignore_file_directive (
238
- & self ,
239
- comments : & SingleThreadedComments ,
240
- module : & swc_ecmascript:: ast:: Module ,
241
- ) -> bool {
242
- comments. with_leading ( module. span . lo ( ) , |module_leading_comments| {
243
- for comment in module_leading_comments. iter ( ) {
244
- if comment. kind == CommentKind :: Line {
245
- let text = comment. text . trim ( ) ;
246
- if self
247
- . ignore_file_directives
248
- . iter ( )
249
- . any ( |directive| directive == text)
250
- {
251
- return true ;
252
- }
253
- }
254
- }
255
- false
256
- } )
257
- }
258
-
259
241
fn filter_diagnostics (
260
242
& self ,
261
243
context : Arc < Context > ,
@@ -322,10 +304,34 @@ impl Linter {
322
304
module : swc_ecmascript:: ast:: Module ,
323
305
comments : SingleThreadedComments ,
324
306
) -> Vec < LintDiagnostic > {
325
- if self . has_ignore_file_directive ( & comments, & module) {
326
- return vec ! [ ] ;
327
- }
328
307
let start = Instant :: now ( ) ;
308
+ let file_ignore_directive = comments. with_leading ( module. span . lo ( ) , |c| {
309
+ let directives = c
310
+ . iter ( )
311
+ . filter_map ( |comment| {
312
+ parse_ignore_comment (
313
+ & self . ignore_file_directives ,
314
+ & * self . ast_parser . source_map ,
315
+ comment,
316
+ true ,
317
+ )
318
+ } )
319
+ . collect :: < Vec < IgnoreDirective > > ( ) ;
320
+
321
+ if directives. is_empty ( ) {
322
+ None
323
+ } else {
324
+ Some ( directives[ 0 ] . clone ( ) )
325
+ }
326
+ } ) ;
327
+
328
+ // If there's a file ignore directive that has no codes specified we must ignore
329
+ // whole file and skip linting it.
330
+ if let Some ( ignore_directive) = & file_ignore_directive {
331
+ if ignore_directive. codes . is_empty ( ) {
332
+ return vec ! [ ] ;
333
+ }
334
+ }
329
335
330
336
let ( leading, trailing) = comments. take_all ( ) ;
331
337
let leading_coms = Rc :: try_unwrap ( leading)
@@ -337,13 +343,17 @@ impl Linter {
337
343
. into_inner ( ) ;
338
344
let trailing = trailing_coms. into_iter ( ) . collect ( ) ;
339
345
340
- let ignore_directives = parse_ignore_directives (
346
+ let mut ignore_directives = parse_ignore_directives (
341
347
& self . ignore_diagnostic_directives ,
342
348
& self . ast_parser . source_map ,
343
349
& leading,
344
350
& trailing,
345
351
) ;
346
352
353
+ if let Some ( ignore_directive) = file_ignore_directive {
354
+ ignore_directives. insert ( 0 , ignore_directive) ;
355
+ }
356
+
347
357
let scope = Arc :: new ( analyze ( & module) ) ;
348
358
let control_flow = Arc :: new ( ControlFlow :: analyze ( & module) ) ;
349
359
@@ -380,19 +390,25 @@ fn parse_ignore_directives(
380
390
381
391
leading_comments. values ( ) . for_each ( |comments| {
382
392
for comment in comments {
383
- if let Some ( ignore) =
384
- parse_ignore_comment ( & ignore_diagnostic_directives, source_map, comment)
385
- {
393
+ if let Some ( ignore) = parse_ignore_comment (
394
+ & ignore_diagnostic_directives,
395
+ source_map,
396
+ comment,
397
+ false ,
398
+ ) {
386
399
ignore_directives. push ( ignore) ;
387
400
}
388
401
}
389
402
} ) ;
390
403
391
404
trailing_comments. values ( ) . for_each ( |comments| {
392
405
for comment in comments {
393
- if let Some ( ignore) =
394
- parse_ignore_comment ( & ignore_diagnostic_directives, source_map, comment)
395
- {
406
+ if let Some ( ignore) = parse_ignore_comment (
407
+ & ignore_diagnostic_directives,
408
+ source_map,
409
+ comment,
410
+ false ,
411
+ ) {
396
412
ignore_directives. push ( ignore) ;
397
413
}
398
414
}
@@ -407,6 +423,7 @@ fn parse_ignore_comment(
407
423
ignore_diagnostic_directives : & [ String ] ,
408
424
source_map : & SourceMap ,
409
425
comment : & Comment ,
426
+ is_global : bool ,
410
427
) -> Option < IgnoreDirective > {
411
428
if comment. kind != CommentKind :: Line {
412
429
return None ;
@@ -415,28 +432,32 @@ fn parse_ignore_comment(
415
432
let comment_text = comment. text . trim ( ) ;
416
433
417
434
for ignore_dir in ignore_diagnostic_directives {
418
- if comment_text. starts_with ( ignore_dir) {
419
- let comment_text = comment_text. strip_prefix ( ignore_dir) . unwrap ( ) ;
420
- let comment_text = IGNORE_COMMENT_CODE_RE . replace_all ( comment_text, "," ) ;
421
- let codes = comment_text
422
- . split ( ',' )
423
- . filter ( |code| !code. is_empty ( ) )
424
- . map ( |code| String :: from ( code. trim ( ) ) )
425
- . collect :: < Vec < String > > ( ) ;
426
-
427
- let location = source_map. lookup_char_pos ( comment. span . lo ( ) ) ;
428
-
429
- let mut used_codes = HashMap :: new ( ) ;
430
- codes. iter ( ) . for_each ( |code| {
431
- used_codes. insert ( code. to_string ( ) , false ) ;
432
- } ) ;
433
-
434
- return Some ( IgnoreDirective {
435
- position : location. into ( ) ,
436
- span : comment. span ,
437
- codes,
438
- used_codes,
439
- } ) ;
435
+ if let Some ( prefix) = comment_text. split_whitespace ( ) . next ( ) {
436
+ if prefix == ignore_dir {
437
+ let comment_text = comment_text. strip_prefix ( ignore_dir) . unwrap ( ) ;
438
+ let comment_text =
439
+ IGNORE_COMMENT_CODE_RE . replace_all ( comment_text, "," ) ;
440
+ let codes = comment_text
441
+ . split ( ',' )
442
+ . filter ( |code| !code. is_empty ( ) )
443
+ . map ( |code| String :: from ( code. trim ( ) ) )
444
+ . collect :: < Vec < String > > ( ) ;
445
+
446
+ let location = source_map. lookup_char_pos ( comment. span . lo ( ) ) ;
447
+
448
+ let mut used_codes = HashMap :: new ( ) ;
449
+ codes. iter ( ) . for_each ( |code| {
450
+ used_codes. insert ( code. to_string ( ) , false ) ;
451
+ } ) ;
452
+
453
+ return Some ( IgnoreDirective {
454
+ position : location. into ( ) ,
455
+ span : comment. span ,
456
+ codes,
457
+ used_codes,
458
+ is_global,
459
+ } ) ;
460
+ }
440
461
}
441
462
}
442
463
0 commit comments