Skip to content

Commit 8858247

Browse files
authored
chore: improve should_proxy_or_freeze logic internally (#10249)
1 parent 7c70c34 commit 8858247

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

.changeset/angry-plums-punch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
chore: improve should_proxy_or_freeze logic internally

packages/svelte/src/compiler/phases/3-transform/client/utils.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ export function serialize_set_binding(node, context, fallback, options) {
293293
if (
294294
context.state.analysis.runes &&
295295
!options?.skip_proxy_and_freeze &&
296-
should_proxy_or_freeze(value)
296+
should_proxy_or_freeze(value, context.state.scope)
297297
) {
298298
const assignment = fallback();
299299
if (assignment.type === 'AssignmentExpression') {
@@ -310,7 +310,7 @@ export function serialize_set_binding(node, context, fallback, options) {
310310
left,
311311
context.state.analysis.runes &&
312312
!options?.skip_proxy_and_freeze &&
313-
should_proxy_or_freeze(value)
313+
should_proxy_or_freeze(value, context.state.scope)
314314
? private_state.kind === 'frozen_state'
315315
? b.call('$.freeze', value)
316316
: b.call('$.proxy', value)
@@ -330,7 +330,7 @@ export function serialize_set_binding(node, context, fallback, options) {
330330
context.state.analysis.runes &&
331331
public_state !== undefined &&
332332
!options?.skip_proxy_and_freeze &&
333-
should_proxy_or_freeze(value)
333+
should_proxy_or_freeze(value, context.state.scope)
334334
) {
335335
const assignment = fallback();
336336
if (assignment.type === 'AssignmentExpression') {
@@ -398,7 +398,7 @@ export function serialize_set_binding(node, context, fallback, options) {
398398
b.id(left_name),
399399
context.state.analysis.runes &&
400400
!options?.skip_proxy_and_freeze &&
401-
should_proxy_or_freeze(value)
401+
should_proxy_or_freeze(value, context.state.scope)
402402
? b.call('$.proxy', value)
403403
: value
404404
);
@@ -408,7 +408,7 @@ export function serialize_set_binding(node, context, fallback, options) {
408408
b.id(left_name),
409409
context.state.analysis.runes &&
410410
!options?.skip_proxy_and_freeze &&
411-
should_proxy_or_freeze(value)
411+
should_proxy_or_freeze(value, context.state.scope)
412412
? b.call('$.freeze', value)
413413
: value
414414
);
@@ -623,8 +623,11 @@ export function get_prop_source(binding, state, name, initial) {
623623
return b.call('$.prop', ...args);
624624
}
625625

626-
/** @param {import('estree').Expression} node */
627-
export function should_proxy_or_freeze(node) {
626+
/**
627+
* @param {import('estree').Expression} node
628+
* @param {import("../../scope.js").Scope | null} scope
629+
*/
630+
export function should_proxy_or_freeze(node, scope) {
628631
if (
629632
!node ||
630633
node.type === 'Literal' ||
@@ -637,5 +640,20 @@ export function should_proxy_or_freeze(node) {
637640
) {
638641
return false;
639642
}
643+
if (node.type === 'Identifier' && scope !== null) {
644+
const binding = scope.get(node.name);
645+
// Let's see if the reference is something that can be proxied or frozen
646+
if (
647+
binding !== null &&
648+
!binding.reassigned &&
649+
binding.initial !== null &&
650+
binding.initial.type !== 'FunctionDeclaration' &&
651+
binding.initial.type !== 'ClassDeclaration' &&
652+
binding.initial.type !== 'ImportDeclaration' &&
653+
binding.initial.type !== 'EachBlock'
654+
) {
655+
return should_proxy_or_freeze(binding.initial, null);
656+
}
657+
}
640658
return true;
641659
}

packages/svelte/src/compiler/phases/3-transform/client/visitors/javascript-runes.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,14 @@ export const javascript_visitors_runes = {
8585

8686
value =
8787
field.kind === 'state'
88-
? b.call('$.source', should_proxy_or_freeze(init) ? b.call('$.proxy', init) : init)
88+
? b.call(
89+
'$.source',
90+
should_proxy_or_freeze(init, state.scope) ? b.call('$.proxy', init) : init
91+
)
8992
: field.kind === 'frozen_state'
9093
? b.call(
9194
'$.source',
92-
should_proxy_or_freeze(init) ? b.call('$.freeze', init) : init
95+
should_proxy_or_freeze(init, state.scope) ? b.call('$.freeze', init) : init
9396
)
9497
: b.call('$.derived', b.thunk(init));
9598
} else {
@@ -238,7 +241,7 @@ export const javascript_visitors_runes = {
238241
*/
239242
const create_state_declarator = (id, value) => {
240243
const binding = /** @type {import('#compiler').Binding} */ (state.scope.get(id.name));
241-
if (should_proxy_or_freeze(value)) {
244+
if (should_proxy_or_freeze(value, state.scope)) {
242245
value = b.call(rune === '$state' ? '$.proxy' : '$.freeze', value);
243246
}
244247
if (is_state_source(binding, state)) {

0 commit comments

Comments
 (0)