Skip to content

Commit 9f83acf

Browse files
committed
Deal with for-of loops for var store autosubscriptions
1 parent 3f12748 commit 9f83acf

File tree

3 files changed

+58
-14
lines changed

3 files changed

+58
-14
lines changed

src/compiler/compile/Component.ts

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import compiler_warnings from './compiler_warnings';
3838
import compiler_errors from './compiler_errors';
3939
import { extract_ignores_above_position, extract_svelte_ignore_from_comments } from '../utils/extract_svelte_ignore';
4040
import check_enable_sourcemap from './utils/check_enable_sourcemap';
41+
import { flatten } from '../utils/flatten';
4142

4243
interface ComponentOptions {
4344
namespace?: string;
@@ -1136,7 +1137,9 @@ export default class Component {
11361137
add_new_props({ type: 'Identifier', name: variable.export_name }, declarator.id, declarator.init);
11371138
node.declarations.splice(index--, 1);
11381139
}
1139-
if (variable.subscribable && (is_props || declarator.init)) {
1140+
1141+
const for_in_of_loop_init = key === 'left' && (parent.type === 'ForInStatement' || parent.type === 'ForOfStatement');
1142+
if (variable.subscribable && (is_props || declarator.init || for_in_of_loop_init)) {
11401143
subscriptions.push(get_subscriptions(variable));
11411144
}
11421145
}
@@ -1147,31 +1150,52 @@ export default class Component {
11471150
throw new Error('export is not at the top level');
11481151
}
11491152

1153+
const flattened_subscriptions = flatten(subscriptions);
1154+
// parent.type === 'Program' or 'BlockStatement' or 'SwitchCase' and key === 'body'
11501155
if (Array.isArray(parent[key])) {
11511156
// If the variable declaration is part of some block, that is, among an array of statements
11521157
// then, we add the subscriptions and the $$props declaration after declaration
11531158
if (subscriptions.length > 0) {
1154-
subscriptions.reverse().forEach((subscription) => {
1155-
parent[key].splice(index + 1, 0, ...subscription);
1156-
});
1159+
parent[key].splice(index + 1, 0, ...flattened_subscriptions);
11571160
}
11581161
if (props.length > 0) {
11591162
// b`` might return a Node array, but the $$props declaration will be flattened later
11601163
parent[key].splice(index + 1, 0, b`let { ${props} } = $$props;`);
1161-
}
1164+
}
11621165
if (node.declarations.length == 0) {
11631166
parent[key].splice(index, 1);
11641167
}
11651168
} else if (subscriptions.length > 0) {
1166-
// If the variable declaration is not part of a block, we instead get a dummy variable setting
1167-
// calling an immediately-invoked function expression containing all the subscription functions
1168-
node.declarations.push({
1169-
type: 'VariableDeclarator',
1170-
id: component.get_unique_name('$$subscriptions', scope),
1171-
init: x`(() => {
1172-
${subscriptions}
1173-
})()`
1174-
});
1169+
// if it is for (var x in array) or for (var x of array)
1170+
// we are transforming from:
1171+
//
1172+
// for (var x of array) {
1173+
// // body
1174+
// }
1175+
// to:
1176+
// for (var x of array) {
1177+
// // subscription inserts
1178+
// // body
1179+
// }
1180+
if (key === 'left' && (parent.type === 'ForInStatement' || parent.type === 'ForOfStatement')) {
1181+
if (parent.body.type !== 'BlockStatement') {
1182+
parent.body = {
1183+
type: 'BlockStatement',
1184+
body: [parent.body]
1185+
};
1186+
}
1187+
parent.body.body.unshift(...flattened_subscriptions);
1188+
} else {
1189+
// If the variable declaration is not part of a block, we instead get a dummy variable setting
1190+
// calling an immediately-invoked function expression containing all the subscription functions
1191+
node.declarations.push({
1192+
type: 'VariableDeclarator',
1193+
id: component.get_unique_name('$$subscriptions', scope),
1194+
init: x`(() => {
1195+
${flattened_subscriptions}
1196+
})()`
1197+
});
1198+
}
11751199
}
11761200

11771201
return this.skip();
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
html: '<p>362880</p><p>9</p><p>object</p><p>function</p>'
3+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script>
2+
import { readable } from "svelte/store";
3+
const array = [];
4+
for (let i = 1; i < 10; i++) {
5+
array.push(readable(i));
6+
}
7+
8+
let ten_factorial = 1;
9+
for (var read of array) {
10+
ten_factorial *= $read;
11+
}
12+
</script>
13+
14+
<p>{ten_factorial}</p>
15+
<p>{$read}</p>
16+
<p>{typeof read}</p>
17+
<p>{typeof read.subscribe}</p>

0 commit comments

Comments
 (0)