@@ -8,6 +8,7 @@ import * as assert from '../../../../utils/assert.js';
88import { get_rune } from '../../../scope.js' ;
99import { get_prop_source , is_prop_source , is_state_source , should_proxy } from '../utils.js' ;
1010import { is_hoisted_function } from '../../utils.js' ;
11+ import { get_value } from './shared/declarations.js' ;
1112
1213/**
1314 * @param {VariableDeclaration } node
@@ -116,7 +117,7 @@ export function VariableDeclaration(node, context) {
116117 }
117118
118119 const args = /** @type {CallExpression } */ ( init ) . arguments ;
119- const value = args . length > 0 ? /** @type {Expression } */ ( context . visit ( args [ 0 ] ) ) : b . void0 ;
120+ const value = /** @type {Expression } */ ( args [ 0 ] ) ?? b . void0 ; // TODO do we need the void 0? can we just omit it altogether?
120121
121122 if ( rune === '$state' || rune === '$state.raw' ) {
122123 /**
@@ -138,15 +139,31 @@ export function VariableDeclaration(node, context) {
138139
139140 if ( declarator . id . type === 'Identifier' ) {
140141 declarations . push (
141- b . declarator ( declarator . id , create_state_declarator ( declarator . id , value ) )
142+ b . declarator (
143+ declarator . id ,
144+ create_state_declarator (
145+ declarator . id ,
146+ /** @type {Expression } */ ( context . visit ( value ) )
147+ )
148+ )
142149 ) ;
143150 } else {
144151 const tmp = b . id ( context . state . scope . generate ( 'tmp' ) ) ;
145- const { paths } = extract_paths ( declarator . id , tmp ) ;
152+ const { inserts, paths } = extract_paths ( declarator . id , tmp ) ;
153+
146154 declarations . push (
147155 b . declarator ( tmp , value ) ,
156+ ...inserts . map ( ( { id, value } ) => {
157+ id . name = context . state . scope . generate ( '$$array' ) ;
158+ context . state . transform [ id . name ] = { read : get_value } ;
159+
160+ return b . declarator (
161+ id ,
162+ b . call ( '$.derived' , /** @type {Expression } */ ( context . visit ( b . thunk ( value ) ) ) )
163+ ) ;
164+ } ) ,
148165 ...paths . map ( ( path ) => {
149- const value = path . expression ;
166+ const value = /** @type { Expression } */ ( context . visit ( path . expression ) ) ;
150167 const binding = context . state . scope . get ( /** @type {Identifier } */ ( path . node ) . name ) ;
151168 return b . declarator (
152169 path . node ,
@@ -163,12 +180,10 @@ export function VariableDeclaration(node, context) {
163180
164181 if ( rune === '$derived' || rune === '$derived.by' ) {
165182 if ( declarator . id . type === 'Identifier' ) {
166- declarations . push (
167- b . declarator (
168- declarator . id ,
169- b . call ( '$.derived' , rune === '$derived.by' ? value : b . thunk ( value ) )
170- )
171- ) ;
183+ let expression = /** @type {Expression } */ ( context . visit ( value ) ) ;
184+ if ( rune === '$derived' ) expression = b . thunk ( expression ) ;
185+
186+ declarations . push ( b . declarator ( declarator . id , b . call ( '$.derived' , expression ) ) ) ;
172187 } else {
173188 const init = /** @type {CallExpression } */ ( declarator . init ) ;
174189
@@ -178,24 +193,32 @@ export function VariableDeclaration(node, context) {
178193 const id = b . id ( context . state . scope . generate ( '$$d' ) ) ;
179194 rhs = b . call ( '$.get' , id ) ;
180195
181- declarations . push (
182- b . declarator ( id , b . call ( '$.derived' , rune === '$derived.by' ? value : b . thunk ( value ) ) )
183- ) ;
196+ let expression = /** @type {Expression } */ ( context . visit ( value ) ) ;
197+ if ( rune === '$derived' ) expression = b . thunk ( expression ) ;
198+
199+ declarations . push ( b . declarator ( id , b . call ( '$.derived' , expression ) ) ) ;
184200 }
185201
186202 const { inserts, paths } = extract_paths ( declarator . id , rhs ) ;
187203
188- for ( const insert of inserts ) {
189- insert . id . name = context . state . scope . generate ( '$$array' ) ;
190- declarations . push ( b . declarator ( insert . id , insert . value ) ) ;
191- }
204+ for ( const { id, value } of inserts ) {
205+ id . name = context . state . scope . generate ( '$$array' ) ;
206+ context . state . transform [ id . name ] = { read : get_value } ;
192207
193- for ( const path of paths ) {
194208 declarations . push (
195- b . declarator ( path . node , b . call ( '$.derived' , b . thunk ( path . expression ) ) )
209+ b . declarator (
210+ id ,
211+ b . call ( '$.derived' , /** @type {Expression } */ ( context . visit ( b . thunk ( value ) ) ) )
212+ )
196213 ) ;
197214 }
215+
216+ for ( const path of paths ) {
217+ const expression = /** @type {Expression } */ ( context . visit ( path . expression ) ) ;
218+ declarations . push ( b . declarator ( path . node , b . call ( '$.derived' , b . thunk ( expression ) ) ) ) ;
219+ }
198220 }
221+
199222 continue ;
200223 }
201224 }
@@ -225,7 +248,7 @@ export function VariableDeclaration(node, context) {
225248 // Turn export let into props. It's really really weird because export let { x: foo, z: [bar]} = ..
226249 // means that foo and bar are the props (i.e. the leafs are the prop names), not x and z.
227250 const tmp = b . id ( context . state . scope . generate ( 'tmp' ) ) ;
228- const { paths } = extract_paths ( declarator . id , tmp ) ;
251+ const { inserts , paths } = extract_paths ( declarator . id , tmp ) ;
229252
230253 declarations . push (
231254 b . declarator (
@@ -234,10 +257,23 @@ export function VariableDeclaration(node, context) {
234257 )
235258 ) ;
236259
260+ for ( const { id, value } of inserts ) {
261+ id . name = context . state . scope . generate ( '$$array' ) ;
262+ context . state . transform [ id . name ] = { read : get_value } ;
263+
264+ declarations . push (
265+ b . declarator (
266+ id ,
267+ b . call ( '$.derived' , /** @type {Expression } */ ( context . visit ( b . thunk ( value ) ) ) )
268+ )
269+ ) ;
270+ }
271+
237272 for ( const path of paths ) {
238273 const name = /** @type {Identifier } */ ( path . node ) . name ;
239274 const binding = /** @type {Binding } */ ( context . state . scope . get ( name ) ) ;
240- const value = path . expression ;
275+ const value = /** @type {Expression } */ ( context . visit ( path . expression ) ) ;
276+
241277 declarations . push (
242278 b . declarator (
243279 path . node ,
@@ -271,7 +307,7 @@ export function VariableDeclaration(node, context) {
271307 declarations . push (
272308 ...create_state_declarators (
273309 declarator ,
274- context . state ,
310+ context ,
275311 /** @type {Expression } */ ( declarator . init && context . visit ( declarator . init ) )
276312 )
277313 ) ;
@@ -291,30 +327,41 @@ export function VariableDeclaration(node, context) {
291327/**
292328 * Creates the output for a state declaration in legacy mode.
293329 * @param {VariableDeclarator } declarator
294- * @param {ComponentClientTransformState } scope
330+ * @param {ComponentContext } context
295331 * @param {Expression } value
296332 */
297- function create_state_declarators ( declarator , { scope , analysis } , value ) {
333+ function create_state_declarators ( declarator , context , value ) {
298334 if ( declarator . id . type === 'Identifier' ) {
299335 return [
300336 b . declarator (
301337 declarator . id ,
302- b . call ( '$.mutable_source' , value , analysis . immutable ? b . true : undefined )
338+ b . call ( '$.mutable_source' , value , context . state . analysis . immutable ? b . true : undefined )
303339 )
304340 ] ;
305341 }
306342
307- const tmp = b . id ( scope . generate ( 'tmp' ) ) ;
308- const { paths } = extract_paths ( declarator . id , tmp ) ;
343+ const tmp = b . id ( context . state . scope . generate ( 'tmp' ) ) ;
344+ const { inserts, paths } = extract_paths ( declarator . id , tmp ) ;
345+
309346 return [
310347 b . declarator ( tmp , value ) ,
348+ ...inserts . map ( ( { id, value } ) => {
349+ id . name = context . state . scope . generate ( '$$array' ) ;
350+ context . state . transform [ id . name ] = { read : get_value } ;
351+
352+ return b . declarator (
353+ id ,
354+ b . call ( '$.derived' , /** @type {Expression } */ ( context . visit ( b . thunk ( value ) ) ) )
355+ ) ;
356+ } ) ,
311357 ...paths . map ( ( path ) => {
312- const value = path . expression ;
313- const binding = scope . get ( /** @type {Identifier } */ ( path . node ) . name ) ;
358+ const value = /** @type {Expression } */ ( context . visit ( path . expression ) ) ;
359+ const binding = context . state . scope . get ( /** @type {Identifier } */ ( path . node ) . name ) ;
360+
314361 return b . declarator (
315362 path . node ,
316363 binding ?. kind === 'state'
317- ? b . call ( '$.mutable_source' , value , analysis . immutable ? b . true : undefined )
364+ ? b . call ( '$.mutable_source' , value , context . state . analysis . immutable ? b . true : undefined )
318365 : value
319366 ) ;
320367 } )
0 commit comments