@@ -20,6 +20,9 @@ export function visit_component(node, context) {
2020 // link this node to all the snippets that it could render, so that we can prune CSS correctly
2121 node . metadata . snippets = new Set ( ) ;
2222
23+ // 'resolved' means we know which snippets this component might render. if it is `false`,
24+ // then `node.metadata.snippets` is populated with every locally defined snippet
25+ // once analysis is complete
2326 let resolved = true ;
2427
2528 for ( const attribute of node . attributes ) {
@@ -34,26 +37,26 @@ export function visit_component(node, context) {
3437
3538 const expression = get_attribute_expression ( attribute ) ;
3639
40+ // given an attribute like `foo={bar}`, if `bar` resolves to an import or a prop
41+ // then we know it doesn't reference a locally defined snippet. if it resolves
42+ // to a `{#snippet bar()}` then we know _which_ snippet it resolves to. in all
43+ // other cases, we can't know (without much more complex static analysis) which
44+ // snippets the component might render, so we treat the component as unresolved
3745 if ( expression . type === 'Identifier' ) {
3846 const binding = context . state . scope . get ( expression . name ) ;
3947
40- if (
41- binding &&
48+ resolved &&=
49+ ! ! binding &&
4250 binding . declaration_kind !== 'import' &&
4351 binding . kind !== 'prop' &&
4452 binding . kind !== 'rest_prop' &&
4553 binding . kind !== 'bindable_prop' &&
46- binding . initial ?. type !== 'SnippetBlock'
47- ) {
48- resolved = false ;
49- }
54+ binding . initial ?. type !== 'SnippetBlock' ;
5055
5156 if ( binding ?. initial ?. type === 'SnippetBlock' ) {
5257 node . metadata . snippets . add ( binding . initial ) ;
5358 }
5459 } else {
55- // we can't safely know which snippets this component could render,
56- // so we deopt. this _could_ result in unused CSS not being discarded
5760 resolved = false ;
5861 }
5962 }
0 commit comments