@@ -24,6 +24,7 @@ import { analyze_css } from './css/css-analyze.js';
24
24
import { prune } from './css/css-prune.js' ;
25
25
import { hash } from './utils.js' ;
26
26
import { warn_unused } from './css/css-warn.js' ;
27
+ import { extract_svelte_ignore } from '../../utils/extract_svelte_ignore.js' ;
27
28
28
29
/**
29
30
* @param {import('#compiler').Script | null } script
@@ -330,7 +331,7 @@ export function analyze_component(root, source, options) {
330
331
} else if ( declaration !== null && Runes . includes ( /** @type {any } */ ( name ) ) ) {
331
332
for ( const { node, path } of references ) {
332
333
if ( path . at ( - 1 ) ?. type === 'CallExpression' ) {
333
- warn ( warnings , node , [ ] , 'store-with-rune-name' , store_name ) ;
334
+ warn ( warnings , node , 'store-with-rune-name' , store_name ) ;
334
335
}
335
336
}
336
337
}
@@ -407,7 +408,7 @@ export function analyze_component(root, source, options) {
407
408
} ;
408
409
409
410
if ( ! options . customElement && root . options ?. customElement ) {
410
- warn ( analysis . warnings , root . options , [ ] , 'missing-custom-element-compile-option' ) ;
411
+ warn ( analysis . warnings , root . options , 'missing-custom-element-compile-option' ) ;
411
412
}
412
413
413
414
if ( analysis . runes ) {
@@ -433,7 +434,8 @@ export function analyze_component(root, source, options) {
433
434
component_slots : new Set ( ) ,
434
435
expression : null ,
435
436
private_derived_state : [ ] ,
436
- function_depth : scope . function_depth
437
+ function_depth : scope . function_depth ,
438
+ ignores : new Set ( )
437
439
} ;
438
440
439
441
walk (
@@ -475,7 +477,8 @@ export function analyze_component(root, source, options) {
475
477
component_slots : new Set ( ) ,
476
478
expression : null ,
477
479
private_derived_state : [ ] ,
478
- function_depth : scope . function_depth
480
+ function_depth : scope . function_depth ,
481
+ ignores : new Set ( )
479
482
} ;
480
483
481
484
walk (
@@ -495,7 +498,7 @@ export function analyze_component(root, source, options) {
495
498
( r ) => r . node !== binding . node && r . path . at ( - 1 ) ?. type !== 'ExportSpecifier'
496
499
) ;
497
500
if ( ! references . length && ! instance . scope . declarations . has ( `$${ name } ` ) ) {
498
- warn ( warnings , binding . node , [ ] , 'unused-export-let' , name ) ;
501
+ warn ( warnings , binding . node , 'unused-export-let' , name ) ;
499
502
}
500
503
}
501
504
}
@@ -535,15 +538,15 @@ export function analyze_component(root, source, options) {
535
538
type === 'AwaitBlock' ||
536
539
type === 'KeyBlock'
537
540
) {
538
- warn ( warnings , binding . node , [ ] , 'non-state-reference' , name ) ;
541
+ warn ( warnings , binding . node , 'non-state-reference' , name ) ;
539
542
continue outer;
540
543
}
541
544
}
542
545
continue inner;
543
546
}
544
547
}
545
548
546
- warn ( warnings , binding . node , [ ] , 'non-state-reference' , name ) ;
549
+ warn ( warnings , binding . node , 'non-state-reference' , name ) ;
547
550
continue outer;
548
551
}
549
552
}
@@ -557,7 +560,13 @@ export function analyze_component(root, source, options) {
557
560
for ( const element of analysis . elements ) {
558
561
prune ( analysis . css . ast , element ) ;
559
562
}
560
- warn_unused ( analysis . css . ast , analysis . warnings ) ;
563
+
564
+ if (
565
+ ! analysis . css . ast . content . comment ||
566
+ ! extract_svelte_ignore ( analysis . css . ast . content . comment . data ) . includes ( 'css-unused-selector' )
567
+ ) {
568
+ warn_unused ( analysis . css . ast , analysis . warnings ) ;
569
+ }
561
570
562
571
outer: for ( const element of analysis . elements ) {
563
572
if ( element . metadata . scoped ) {
@@ -679,7 +688,7 @@ const legacy_scope_tweaker = {
679
688
( d ) => d . scope === state . analysis . module . scope && d . declaration_kind !== 'const'
680
689
)
681
690
) {
682
- warn ( state . analysis . warnings , node , path , 'module-script-reactive-declaration' ) ;
691
+ warn ( state . analysis . warnings , node , 'module-script-reactive-declaration' ) ;
683
692
}
684
693
685
694
if (
@@ -1045,6 +1054,65 @@ const function_visitor = (node, context) => {
1045
1054
1046
1055
/** @type {import('./types').Visitors } */
1047
1056
const common_visitors = {
1057
+ _ ( node , context ) {
1058
+ // @ts -expect-error
1059
+ const comments = /** @type {import('estree').Comment[] } */ ( node . leadingComments ) ;
1060
+
1061
+ if ( comments ) {
1062
+ /** @type {string[] } */
1063
+ const ignores = [ ] ;
1064
+
1065
+ for ( const comment of comments ) {
1066
+ ignores . push ( ...extract_svelte_ignore ( comment . value ) ) ;
1067
+ }
1068
+
1069
+ if ( ignores . length > 0 ) {
1070
+ // @ts -expect-error see below
1071
+ node . ignores = new Set ( [ ...context . state . ignores , ...ignores ] ) ;
1072
+ }
1073
+ }
1074
+
1075
+ // @ts -expect-error
1076
+ if ( node . ignores ) {
1077
+ context . next ( {
1078
+ ...context . state ,
1079
+ // @ts -expect-error see below
1080
+ ignores : node . ignores
1081
+ } ) ;
1082
+ } else if ( context . state . ignores . size > 0 ) {
1083
+ // @ts -expect-error
1084
+ node . ignores = context . state . ignores ;
1085
+ }
1086
+ } ,
1087
+ Fragment ( node , context ) {
1088
+ /** @type {string[] } */
1089
+ let ignores = [ ] ;
1090
+
1091
+ for ( const child of node . nodes ) {
1092
+ if ( child . type === 'Text' && child . data . trim ( ) === '' ) {
1093
+ continue ;
1094
+ }
1095
+
1096
+ if ( child . type === 'Comment' ) {
1097
+ ignores . push ( ...extract_svelte_ignore ( child . data ) ) ;
1098
+ } else {
1099
+ const combined_ignores = new Set ( context . state . ignores ) ;
1100
+ for ( const ignore of ignores ) combined_ignores . add ( ignore ) ;
1101
+
1102
+ if ( combined_ignores . size > 0 ) {
1103
+ // TODO this is a grotesque hack that's made necessary by the fact that
1104
+ // we can't call `context.visit(...)` here, because we do the convoluted
1105
+ // visitor merging thing. I'm increasingly of the view that we should
1106
+ // rearchitect this stuff and have a single visitor per node. It'd be
1107
+ // more efficient and much simpler.
1108
+ // @ts -expect-error
1109
+ child . ignores = combined_ignores ;
1110
+ }
1111
+
1112
+ ignores = [ ] ;
1113
+ }
1114
+ }
1115
+ } ,
1048
1116
Attribute ( node , context ) {
1049
1117
if ( node . value === true ) return ;
1050
1118
@@ -1142,7 +1210,7 @@ const common_visitors = {
1142
1210
binding . kind === 'derived' ) &&
1143
1211
context . state . function_depth === binding . scope . function_depth
1144
1212
) {
1145
- warn ( context . state . analysis . warnings , node , context . path , 'static-state-reference' ) ;
1213
+ warn ( context . state . analysis . warnings , node , 'static-state-reference' ) ;
1146
1214
}
1147
1215
}
1148
1216
} ,
0 commit comments