@@ -15,6 +15,7 @@ import {
1515import { is_reserved , is_rune } from '../../utils.js' ;
1616import { determine_slot } from '../utils/slot.js' ;
1717import { validate_identifier_name } from './2-analyze/visitors/shared/utils.js' ;
18+ import { bind_window_scroll } from 'svelte/internal/client' ;
1819
1920export const UNKNOWN = Symbol ( 'unknown' ) ;
2021/** Includes `BigInt` */
@@ -173,14 +174,24 @@ class Evaluation {
173174 binding . kind === 'bindable_prop' ;
174175
175176 if ( ! binding . updated && binding . initial !== null && ! is_prop ) {
177+ console . log ( binding . initial ) ;
176178 const evaluation = binding . scope . evaluate ( /** @type {Expression } */ ( binding . initial ) ) ;
177179 for ( const value of evaluation . values ) {
178180 this . values . add ( value ) ;
179181 }
180182 break ;
181183 }
182-
183- // TODO each index is always defined
184+ if (
185+ binding . kind === 'each' &&
186+ binding . initial ?. type === 'EachBlock' &&
187+ binding . initial . index === expression . name
188+ ) {
189+ this . values . add ( NUMBER ) ;
190+ break ;
191+ }
192+ } else if ( expression . name === 'undefined' ) {
193+ this . values . add ( undefined ) ;
194+ break ;
184195 }
185196
186197 // TODO glean what we can from reassignments
@@ -336,6 +347,124 @@ class Evaluation {
336347 break ;
337348 }
338349
350+ case 'CallExpression' :
351+ {
352+ const rune = get_rune ( expression , scope ) ;
353+ if (
354+ rune &&
355+ scope . get (
356+ object ( /** @type {Identifier | MemberExpression } */ ( expression . callee ) ) ?. name ?? ''
357+ ) === null
358+ ) {
359+ switch ( rune ) {
360+ case '$state' :
361+ case '$state.raw' :
362+ if ( expression . arguments . length ) {
363+ const evaluated = scope . evaluate (
364+ /** @type {Expression } */ ( expression . arguments [ 0 ] )
365+ ) ;
366+ for ( let value of evaluated . values ) {
367+ this . values . add ( value ) ;
368+ }
369+ } else {
370+ this . values . add ( undefined ) ;
371+ }
372+ break ;
373+ case '$props.id' :
374+ this . values . add ( STRING ) ;
375+ break ;
376+ case '$effect.tracking' :
377+ this . values . add ( false ) ;
378+ this . values . add ( true ) ;
379+ break ;
380+ case '$derived' : {
381+ const evaluated = scope . evaluate (
382+ /** @type {Expression } */ ( expression . arguments [ 0 ] )
383+ ) ;
384+ for ( let value of evaluated . values ) {
385+ this . values . add ( value ) ;
386+ }
387+ break ;
388+ }
389+ case '$derived.by' :
390+ if ( expression . arguments [ 0 ] ?. type === 'ArrowFunctionExpression' ) {
391+ if ( expression . arguments [ 0 ] . body ?. type !== 'BlockStatement' ) {
392+ const evaluated = scope . evaluate (
393+ /** @type {Expression } */ ( expression . arguments [ 0 ] . body )
394+ ) ;
395+ for ( let value of evaluated . values ) {
396+ this . values . add ( value ) ;
397+ }
398+ break ;
399+ }
400+ }
401+ default : {
402+ this . values . add ( UNKNOWN ) ;
403+ }
404+ }
405+ } else if (
406+ expression . callee . type === 'Identifier' &&
407+ scope . get ( expression . callee . name ) === null
408+ ) {
409+ switch ( expression . callee . name ) {
410+ case 'Number' : {
411+ if ( expression . arguments . length ) {
412+ const arg = scope . evaluate ( /** @type {Expression } */ ( expression . arguments [ 0 ] ) ) ;
413+ if ( arg . is_known ) {
414+ this . values . add ( Number ( arg . value ) ) ;
415+ } else if ( arg . is_number ) {
416+ this . values . add ( NUMBER ) ;
417+ } else {
418+ for ( let value of arg . values ) {
419+ switch ( value ) {
420+ case STRING :
421+ case NUMBER :
422+ case UNKNOWN :
423+ this . values . add ( NUMBER ) ;
424+ break ;
425+ default :
426+ this . values . add ( Number ( value ) ) ;
427+ }
428+ }
429+ }
430+ } else {
431+ this . values . add ( 0 ) ;
432+ }
433+ break ;
434+ }
435+ case 'String' :
436+ if ( expression . arguments . length ) {
437+ const arg = scope . evaluate ( /** @type {Expression } */ ( expression . arguments [ 0 ] ) ) ;
438+ if ( arg . is_known ) {
439+ this . values . add ( String ( arg . value ) ) ;
440+ } else if ( arg . is_number || arg . is_string ) {
441+ this . values . add ( STRING ) ;
442+ } else {
443+ for ( let value of arg . values ) {
444+ switch ( value ) {
445+ case STRING :
446+ case NUMBER :
447+ case UNKNOWN :
448+ this . values . add ( STRING ) ;
449+ break ;
450+ default :
451+ this . values . add ( String ( value ) ) ;
452+ }
453+ }
454+ }
455+ } else {
456+ this . values . add ( '' ) ;
457+ }
458+ break ;
459+ default :
460+ this . values . add ( UNKNOWN ) ;
461+ }
462+ } else {
463+ this . values . add ( UNKNOWN ) ;
464+ }
465+ }
466+ break ;
467+
339468 default : {
340469 this . values . add ( UNKNOWN ) ;
341470 }
0 commit comments