Skip to content

Commit 2861ad6

Browse files
committed
fix: correct increment/decrement code generation
fixes #10226
1 parent 0fd1c92 commit 2861ad6

File tree

6 files changed

+67
-19
lines changed

6 files changed

+67
-19
lines changed

.changeset/honest-buses-add.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+
fix: correct increment/decrement code generation

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,16 @@ export const global_visitors = {
8383
argument.property.type === 'PrivateIdentifier' &&
8484
context.state.private_state.has(argument.property.name)
8585
) {
86-
let fn = node.operator === '++' ? '$.increment' : '$.decrement';
87-
return b.call(fn, argument);
86+
let fn = '$.update';
87+
if (node.prefix) fn += '_pre';
88+
89+
/** @type {import('estree').Expression[]} */
90+
const args = [argument];
91+
if (node.operator === '--') {
92+
args.push(b.literal(-1));
93+
}
94+
95+
return b.call(fn, ...args);
8896
} else {
8997
// turn it into an IIFEE assignment expression: i++ -> (() => { const $$value = i; i+=1; return $$value; })
9098
const assignment = b.assignment(

packages/svelte/src/compiler/phases/3-transform/server/transform-server.js

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -511,24 +511,17 @@ const global_visitors = {
511511
const { state, next } = context;
512512
const argument = node.argument;
513513

514-
if (argument.type === 'Identifier') {
515-
const binding = state.scope.get(argument.name);
516-
const is_store = binding?.kind === 'store_sub';
517-
const name = is_store ? argument.name.slice(1) : argument.name;
518-
// use runtime functions for smaller output
519-
if (is_store) {
520-
let fn = node.operator === '++' ? '$.increment' : '$.decrement';
521-
if (node.prefix) fn += '_pre';
522-
523-
if (is_store) {
524-
fn += '_store';
525-
return b.call(fn, serialize_get_binding(b.id(name), state), b.call('$' + name));
526-
} else {
527-
return b.call(fn, b.id(name));
528-
}
529-
} else {
530-
return next();
514+
if (argument.type === 'Identifier' && state.scope.get(argument.name)?.kind === 'store_sub') {
515+
let fn = '$.update_store';
516+
if (node.prefix) fn += '_pre';
517+
518+
/** @type {import('estree').Expression[]} */
519+
const args = [b.id('$$store_subs'), b.literal(argument.name), b.id(argument.name.slice(1))];
520+
if (node.operator === '--') {
521+
args.push(b.literal(-1));
531522
}
523+
524+
return b.call(fn, ...args);
532525
}
533526
return next();
534527
}

packages/svelte/src/internal/server/index.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,32 @@ export function mutate_store(store_values, store_name, store, expression) {
407407
return expression;
408408
}
409409

410+
/**
411+
* @param {Record<string, [any, any, any]>} store_values
412+
* @param {string} store_name
413+
* @param {import('../client/types.js').Store<number>} store
414+
* @param {1 | -1} [d]
415+
* @returns {number}
416+
*/
417+
export function update_store(store_values, store_name, store, d = 1) {
418+
let store_value = store_get(store_values, store_name, store);
419+
store.set(store_value + d);
420+
return store_value;
421+
}
422+
423+
/**
424+
* @param {Record<string, [any, any, any]>} store_values
425+
* @param {string} store_name
426+
* @param {import('../client/types.js').Store<number>} store
427+
* @param {1 | -1} [d]
428+
* @returns {number}
429+
*/
430+
export function update_store_pre(store_values, store_name, store, d = 1) {
431+
const value = store_get(store_values, store_name, store) + d;
432+
store.set(value);
433+
return value;
434+
}
435+
410436
/** @param {Record<string, [any, any, any]>} store_values */
411437
export function unsubscribe_stores(store_values) {
412438
for (const store_name in store_values) {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
html: `0 0 2 2 0`
5+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script lang="ts">
2+
import { writable } from "svelte/store";
3+
4+
let x = writable(0);
5+
const a = $x++;
6+
const b = ++$x;
7+
const c = $x--;
8+
const d = --$x;
9+
</script>
10+
11+
{$x} {a} {b} {c} {d}

0 commit comments

Comments
 (0)