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 ( if (
context.state.analysis.runes && context.state.analysis.runes &&
!options?.skip_proxy_and_freeze && !options?.skip_proxy_and_freeze &&
should_proxy_or_freeze(value) should_proxy_or_freeze(value, context.state.scope)
) { ) {
const assignment = fallback(); const assignment = fallback();
if (assignment.type === 'AssignmentExpression') { if (assignment.type === 'AssignmentExpression') {
@ -310,7 +310,7 @@ export function serialize_set_binding(node, context, fallback, options) {
left, left,
context.state.analysis.runes && context.state.analysis.runes &&
!options?.skip_proxy_and_freeze && !options?.skip_proxy_and_freeze &&
should_proxy_or_freeze(value) should_proxy_or_freeze(value, context.state.scope)
? private_state.kind === 'frozen_state' ? private_state.kind === 'frozen_state'
? b.call('$.freeze', value) ? b.call('$.freeze', value)
: b.call('$.proxy', value) : b.call('$.proxy', value)
@ -330,7 +330,7 @@ export function serialize_set_binding(node, context, fallback, options) {
context.state.analysis.runes && context.state.analysis.runes &&
public_state !== undefined && public_state !== undefined &&
!options?.skip_proxy_and_freeze && !options?.skip_proxy_and_freeze &&
should_proxy_or_freeze(value) should_proxy_or_freeze(value, context.state.scope)
) { ) {
const assignment = fallback(); const assignment = fallback();
if (assignment.type === 'AssignmentExpression') { if (assignment.type === 'AssignmentExpression') {
@ -398,7 +398,7 @@ export function serialize_set_binding(node, context, fallback, options) {
b.id(left_name), b.id(left_name),
context.state.analysis.runes && context.state.analysis.runes &&
!options?.skip_proxy_and_freeze && !options?.skip_proxy_and_freeze &&
should_proxy_or_freeze(value) should_proxy_or_freeze(value, context.state.scope)
? b.call('$.proxy', value) ? b.call('$.proxy', value)
: value : value
); );
@ -408,7 +408,7 @@ export function serialize_set_binding(node, context, fallback, options) {
b.id(left_name), b.id(left_name),
context.state.analysis.runes && context.state.analysis.runes &&
!options?.skip_proxy_and_freeze && !options?.skip_proxy_and_freeze &&
should_proxy_or_freeze(value) should_proxy_or_freeze(value, context.state.scope)
? b.call('$.freeze', value) ? b.call('$.freeze', value)
: value : value
); );
@ -623,8 +623,11 @@ export function get_prop_source(binding, state, name, initial) {
return b.call('$.prop', ...args); 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 ( if (
!node || !node ||
node.type === 'Literal' || node.type === 'Literal' ||
@ -637,5 +640,20 @@ export function should_proxy_or_freeze(node) {
) { ) {
return false; 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; return true;
} }

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

Loading…
Cancel
Save