chore: improve should_proxy_or_freeze logic internally (#10249)

pull/10257/head
Dominic Gannaway 11 months ago committed by GitHub
parent 7c70c346f8
commit 88582479f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
chore: improve should_proxy_or_freeze logic internally

@ -293,7 +293,7 @@ export function serialize_set_binding(node, context, fallback, options) {
if (
context.state.analysis.runes &&
!options?.skip_proxy_and_freeze &&
should_proxy_or_freeze(value)
should_proxy_or_freeze(value, context.state.scope)
) {
const assignment = fallback();
if (assignment.type === 'AssignmentExpression') {
@ -310,7 +310,7 @@ export function serialize_set_binding(node, context, fallback, options) {
left,
context.state.analysis.runes &&
!options?.skip_proxy_and_freeze &&
should_proxy_or_freeze(value)
should_proxy_or_freeze(value, context.state.scope)
? private_state.kind === 'frozen_state'
? b.call('$.freeze', value)
: b.call('$.proxy', value)
@ -330,7 +330,7 @@ export function serialize_set_binding(node, context, fallback, options) {
context.state.analysis.runes &&
public_state !== undefined &&
!options?.skip_proxy_and_freeze &&
should_proxy_or_freeze(value)
should_proxy_or_freeze(value, context.state.scope)
) {
const assignment = fallback();
if (assignment.type === 'AssignmentExpression') {
@ -398,7 +398,7 @@ export function serialize_set_binding(node, context, fallback, options) {
b.id(left_name),
context.state.analysis.runes &&
!options?.skip_proxy_and_freeze &&
should_proxy_or_freeze(value)
should_proxy_or_freeze(value, context.state.scope)
? b.call('$.proxy', value)
: value
);
@ -408,7 +408,7 @@ export function serialize_set_binding(node, context, fallback, options) {
b.id(left_name),
context.state.analysis.runes &&
!options?.skip_proxy_and_freeze &&
should_proxy_or_freeze(value)
should_proxy_or_freeze(value, context.state.scope)
? b.call('$.freeze', value)
: value
);
@ -623,8 +623,11 @@ export function get_prop_source(binding, state, name, initial) {
return b.call('$.prop', ...args);
}
/** @param {import('estree').Expression} node */
export function should_proxy_or_freeze(node) {
/**
* @param {import('estree').Expression} node
* @param {import("../../scope.js").Scope | null} scope
*/
export function should_proxy_or_freeze(node, scope) {
if (
!node ||
node.type === 'Literal' ||
@ -637,5 +640,20 @@ export function should_proxy_or_freeze(node) {
) {
return false;
}
if (node.type === 'Identifier' && scope !== null) {
const binding = scope.get(node.name);
// Let's see if the reference is something that can be proxied or frozen
if (
binding !== null &&
!binding.reassigned &&
binding.initial !== null &&
binding.initial.type !== 'FunctionDeclaration' &&
binding.initial.type !== 'ClassDeclaration' &&
binding.initial.type !== 'ImportDeclaration' &&
binding.initial.type !== 'EachBlock'
) {
return should_proxy_or_freeze(binding.initial, null);
}
}
return true;
}

@ -85,11 +85,14 @@ export const javascript_visitors_runes = {
value =
field.kind === 'state'
? b.call('$.source', should_proxy_or_freeze(init) ? b.call('$.proxy', init) : init)
? b.call(
'$.source',
should_proxy_or_freeze(init, state.scope) ? b.call('$.proxy', init) : init
)
: field.kind === 'frozen_state'
? b.call(
'$.source',
should_proxy_or_freeze(init) ? b.call('$.freeze', init) : init
should_proxy_or_freeze(init, state.scope) ? b.call('$.freeze', init) : init
)
: b.call('$.derived', b.thunk(init));
} else {
@ -238,7 +241,7 @@ export const javascript_visitors_runes = {
*/
const create_state_declarator = (id, value) => {
const binding = /** @type {import('#compiler').Binding} */ (state.scope.get(id.name));
if (should_proxy_or_freeze(value)) {
if (should_proxy_or_freeze(value, state.scope)) {
value = b.call(rune === '$state' ? '$.proxy' : '$.freeze', value);
}
if (is_state_source(binding, state)) {

Loading…
Cancel
Save