@ -65,18 +65,20 @@ export function serialize_get_binding(node, state) {
return binding . expression ;
}
if ( binding . kind === 'prop' && binding . node . name === '$$props' ) {
// Special case for $$props which only exists in the old world
return node ;
}
if ( binding . kind === 'prop' ) {
if ( binding . node . name === '$$props' ) {
// Special case for $$props which only exists in the old world
// TODO this probably shouldn't have a 'prop' binding kind
return node ;
}
if (
binding . kind === 'prop' &&
! ( state . analysis . immutable ? binding . reassigned : binding . mutated ) &&
! binding . initial &&
! state . analysis . accessors
) {
return b . call ( node ) ;
if (
! state . analysis . accessors &&
! ( state . analysis . immutable ? binding . reassigned : binding . mutated ) &&
! binding . initial
) {
return b . member ( b . id ( '$$props' ) , node ) ;
}
}
if ( binding . kind === 'legacy_reactive_import' ) {
@ -343,67 +345,53 @@ export function serialize_hoistable_params(node, context) {
}
/ * *
*
* @ param { import ( '#compiler' ) . Binding } binding
* @ param { import ( './types' ) . ComponentClientTransformState } state
* @ param { string } name
* @ param { import ( 'estree' ) . Expression | null } [ default_value ]
* @ param { import ( 'estree' ) . Expression | null } [ initial ]
* @ returns
* /
export function get _prop s_method ( binding , state , name , default _value ) {
export function get _prop _source ( state , name , initial ) {
/** @type {import('estree').Expression[]} */
const args = [ b . id ( '$$props' ) , b . literal ( name ) ] ;
// Use $.prop_source in the following cases:
// - accessors/mutated: needs to be able to set the prop value from within
// - default value: we set the fallback value only initially, and it's not possible to know this timing in $.prop
const needs _source =
default _value ||
state . analysis . accessors ||
( state . analysis . immutable ? binding . reassigned : binding . mutated ) ;
if ( needs _source ) {
let flags = 0 ;
let flags = 0 ;
/** @type {import('estree').Expression | undefined} */
let arg ;
if ( state . analysis . immutable ) {
flags |= PROPS _IS _IMMUTABLE ;
}
if ( state . analysis . immutable ) {
flags |= PROPS _IS _ IMMUTABLE ;
}
if ( state . analysis . runes ) {
flags |= PROPS _IS _RUNES ;
}
if ( state . analysis . runes ) {
flags |= PROPS _IS _RUNES ;
}
/** @type {import('estree').Expression | undefined} */
let arg ;
if ( default _value ) {
// To avoid eagerly evaluating the right-hand-side, we wrap it in a thunk if necessary
if ( is _simple _expression ( default _value ) ) {
arg = default _value ;
if ( initial ) {
// To avoid eagerly evaluating the right-hand-side, we wrap it in a thunk if necessary
if ( is _simple _expression ( initial ) ) {
arg = initial ;
} else {
if (
initial . type === 'CallExpression' &&
initial . callee . type === 'Identifier' &&
initial . arguments . length === 0
) {
arg = initial . callee ;
} else {
if (
default _value . type === 'CallExpression' &&
default _value . callee . type === 'Identifier' &&
default _value . arguments . length === 0
) {
arg = default _value . callee ;
} else {
arg = b . thunk ( default _value ) ;
}
flags |= PROPS _CALL _DEFAULT _VALUE ;
arg = b . thunk ( initial ) ;
}
}
if ( flags || arg ) {
args . push ( b . literal ( flags ) ) ;
if ( arg ) args . push ( arg ) ;
flags |= PROPS _CALL _DEFAULT _VALUE ;
}
}
return b . call ( '$.prop_source' , ... args ) ;
if ( flags || arg ) {
args . push ( b . literal ( flags ) ) ;
if ( arg ) args . push ( arg ) ;
}
return b . call ( '$.prop ', ... args ) ;
return b . call ( '$.prop _source ', ... args ) ;
}
/ * *