Skip to content

Commit

Permalink
fix: correct increment/decrement code generation
Browse files Browse the repository at this point in the history
fixes #10226
  • Loading branch information
dummdidumm committed Jan 19, 2024
1 parent 0fd1c92 commit 2861ad6
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/honest-buses-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte": patch
---

fix: correct increment/decrement code generation
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,16 @@ export const global_visitors = {
argument.property.type === 'PrivateIdentifier' &&
context.state.private_state.has(argument.property.name)
) {
let fn = node.operator === '++' ? '$.increment' : '$.decrement';
return b.call(fn, argument);
let fn = '$.update';
if (node.prefix) fn += '_pre';

/** @type {import('estree').Expression[]} */
const args = [argument];
if (node.operator === '--') {
args.push(b.literal(-1));
}

return b.call(fn, ...args);
} else {
// turn it into an IIFEE assignment expression: i++ -> (() => { const $$value = i; i+=1; return $$value; })
const assignment = b.assignment(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -511,24 +511,17 @@ const global_visitors = {
const { state, next } = context;
const argument = node.argument;

if (argument.type === 'Identifier') {
const binding = state.scope.get(argument.name);
const is_store = binding?.kind === 'store_sub';
const name = is_store ? argument.name.slice(1) : argument.name;
// use runtime functions for smaller output
if (is_store) {
let fn = node.operator === '++' ? '$.increment' : '$.decrement';
if (node.prefix) fn += '_pre';

if (is_store) {
fn += '_store';
return b.call(fn, serialize_get_binding(b.id(name), state), b.call('$' + name));
} else {
return b.call(fn, b.id(name));
}
} else {
return next();
if (argument.type === 'Identifier' && state.scope.get(argument.name)?.kind === 'store_sub') {
let fn = '$.update_store';
if (node.prefix) fn += '_pre';

/** @type {import('estree').Expression[]} */
const args = [b.id('$$store_subs'), b.literal(argument.name), b.id(argument.name.slice(1))];
if (node.operator === '--') {
args.push(b.literal(-1));
}

return b.call(fn, ...args);
}
return next();
}
Expand Down
26 changes: 26 additions & 0 deletions packages/svelte/src/internal/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,32 @@ export function mutate_store(store_values, store_name, store, expression) {
return expression;
}

/**
* @param {Record<string, [any, any, any]>} store_values
* @param {string} store_name
* @param {import('../client/types.js').Store<number>} store
* @param {1 | -1} [d]
* @returns {number}
*/
export function update_store(store_values, store_name, store, d = 1) {
let store_value = store_get(store_values, store_name, store);
store.set(store_value + d);
return store_value;
}

/**
* @param {Record<string, [any, any, any]>} store_values
* @param {string} store_name
* @param {import('../client/types.js').Store<number>} store
* @param {1 | -1} [d]
* @returns {number}
*/
export function update_store_pre(store_values, store_name, store, d = 1) {
const value = store_get(store_values, store_name, store) + d;
store.set(value);
return value;
}

/** @param {Record<string, [any, any, any]>} store_values */
export function unsubscribe_stores(store_values) {
for (const store_name in store_values) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { test } from '../../test';

export default test({
html: `0 0 2 2 0`
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts">
import { writable } from "svelte/store";
let x = writable(0);
const a = $x++;
const b = ++$x;
const c = $x--;
const d = --$x;
</script>

{$x} {a} {b} {c} {d}

0 comments on commit 2861ad6

Please sign in to comment.