@@ -370,41 +370,67 @@ function is_pure_expression(expression) {
370370 // It's supposed that values do not have custom @@toPrimitive() or toString(),
371371 // which may be implicitly called in expressions like `a + b`, `a & b`, `+a`, `str: ${a}`
372372 switch ( expression . type ) {
373- case "ArrayExpression" : return expression . elements . every ( ( element ) => element == null || ( element . type === "SpreadElement" ? false : is_pure_expression ( element ) ) ) ;
374- case "BinaryExpression" : return expression . left . type !== "PrivateIdentifier" && is_pure_expression ( expression . left ) && is_pure_expression ( expression . right ) ;
375- case "ConditionalExpression" : return is_pure_expression ( expression . test ) && is_pure_expression ( expression . consequent ) && is_pure_expression ( expression . alternate ) ;
376- case "Identifier" : return true ;
377- case "Literal" : return true ;
378- case "LogicalExpression" : return is_pure_expression ( expression . left ) && is_pure_expression ( expression . right ) ;
379- case "MetaProperty" : return true ; // new.target
380- case "ObjectExpression" : return expression . properties . every ( ( property ) =>
381- property . type !== "SpreadElement"
382- && property . key . type !== "PrivateIdentifier"
383- && is_pure_expression ( property . key )
384- && is_pure_expression ( property . value )
385- ) ;
386- case "SequenceExpression" : return expression . expressions . every ( is_pure_expression ) ;
387- case "TemplateLiteral" : return expression . expressions . every ( is_pure_expression ) ;
388- case "ThisExpression" : return true ;
389- case "UnaryExpression" : return is_pure_expression ( expression . argument ) ;
390- case "YieldExpression" : return expression . argument == null || is_pure_expression ( expression . argument ) ;
391-
392- case "ArrayPattern" :
393- case "ArrowFunctionExpression" :
394- case "AssignmentExpression" :
395- case "AssignmentPattern" :
396- case "AwaitExpression" :
397- case "CallExpression" :
398- case "ChainExpression" :
399- case "ClassExpression" :
400- case "FunctionExpression" :
401- case "ImportExpression" :
402- case "MemberExpression" :
403- case "NewExpression" :
404- case "ObjectPattern" :
405- case "RestElement" :
406- case "TaggedTemplateExpression" :
407- case "UpdateExpression" :
373+ case 'ArrayExpression' :
374+ return expression . elements . every (
375+ ( element ) =>
376+ element == null ||
377+ ( element . type === 'SpreadElement' ? false : is_pure_expression ( element ) )
378+ ) ;
379+ case 'BinaryExpression' :
380+ return (
381+ expression . left . type !== 'PrivateIdentifier' &&
382+ is_pure_expression ( expression . left ) &&
383+ is_pure_expression ( expression . right )
384+ ) ;
385+ case 'ConditionalExpression' :
386+ return (
387+ is_pure_expression ( expression . test ) &&
388+ is_pure_expression ( expression . consequent ) &&
389+ is_pure_expression ( expression . alternate )
390+ ) ;
391+ case 'Identifier' :
392+ return true ;
393+ case 'Literal' :
394+ return true ;
395+ case 'LogicalExpression' :
396+ return is_pure_expression ( expression . left ) && is_pure_expression ( expression . right ) ;
397+ case 'MetaProperty' :
398+ return true ; // new.target
399+ case 'ObjectExpression' :
400+ return expression . properties . every (
401+ ( property ) =>
402+ property . type !== 'SpreadElement' &&
403+ property . key . type !== 'PrivateIdentifier' &&
404+ is_pure_expression ( property . key ) &&
405+ is_pure_expression ( property . value )
406+ ) ;
407+ case 'SequenceExpression' :
408+ return expression . expressions . every ( is_pure_expression ) ;
409+ case 'TemplateLiteral' :
410+ return expression . expressions . every ( is_pure_expression ) ;
411+ case 'ThisExpression' :
412+ return true ;
413+ case 'UnaryExpression' :
414+ return is_pure_expression ( expression . argument ) ;
415+ case 'YieldExpression' :
416+ return expression . argument == null || is_pure_expression ( expression . argument ) ;
417+
418+ case 'ArrayPattern' :
419+ case 'ArrowFunctionExpression' :
420+ case 'AssignmentExpression' :
421+ case 'AssignmentPattern' :
422+ case 'AwaitExpression' :
423+ case 'CallExpression' :
424+ case 'ChainExpression' :
425+ case 'ClassExpression' :
426+ case 'FunctionExpression' :
427+ case 'ImportExpression' :
428+ case 'MemberExpression' :
429+ case 'NewExpression' :
430+ case 'ObjectPattern' :
431+ case 'RestElement' :
432+ case 'TaggedTemplateExpression' :
433+ case 'UpdateExpression' :
408434 return false ;
409435 }
410436}
@@ -426,23 +452,27 @@ export function build_legacy_expression(expression, context) {
426452 for ( const [ name , nodes ] of context . state . scope . references ) {
427453 const binding = context . state . scope . get ( name ) ;
428454
429- if ( binding === null || binding . kind === 'normal' && binding . declaration_kind !== 'import' ) continue ;
455+ if ( binding === null || ( binding . kind === 'normal' && binding . declaration_kind !== 'import' ) )
456+ continue ;
430457
431458 let used = false ;
432459 for ( const { node, path } of nodes ) {
433- const expressionIdx = path . indexOf ( expression ) ;
434- if ( expressionIdx < 0 ) continue ;
460+ const expression_idx = path . indexOf ( expression ) ;
461+ if ( expression_idx < 0 ) continue ;
435462 // in Svelte 4, #if, #each and #await copy context, so assignments
436463 // aren't propagated to the parent block / component root
437- const track_assignment = ! path . find ( ( node , i ) =>
438- i < expressionIdx - 1 && [ "IfBlock" , "EachBlock" , "AwaitBlock" ] . includes ( node . type )
439- )
464+ const track_assignment = ! path . find (
465+ ( node , i ) =>
466+ i < expression_idx - 1 && [ 'IfBlock' , 'EachBlock' , 'AwaitBlock' ] . includes ( node . type )
467+ ) ;
440468 if ( track_assignment ) {
441469 used = true ;
442470 break ;
443471 }
444- const assignment = /** @type {AssignmentExpression|undefined } */ ( path . find ( ( node , i ) => i >= expressionIdx && node . type === "AssignmentExpression" ) ) ;
445- if ( ! assignment || assignment . left !== node && ! path . includes ( assignment . left ) ) {
472+ const assignment = /** @type {AssignmentExpression|undefined } */ (
473+ path . find ( ( node , i ) => i >= expression_idx && node . type === 'AssignmentExpression' )
474+ ) ;
475+ if ( ! assignment || ( assignment . left !== node && ! path . includes ( assignment . left ) ) ) {
446476 used = true ;
447477 break ;
448478 }
@@ -461,4 +491,4 @@ export function build_legacy_expression(expression, context) {
461491 }
462492
463493 return b . sequence ( [ ...sequence , b . call ( '$.untrack' , b . thunk ( serialized_expression ) ) ] ) ;
464- }
494+ }
0 commit comments