Skip to content

Commit c9cf65c

Browse files
authored
Merge pull request #3518 from sveltejs/gh-3505
fix code generation for if-else with static conditions
2 parents 686aa0b + 1ef9575 commit c9cf65c

File tree

7 files changed

+152
-89
lines changed

7 files changed

+152
-89
lines changed

src/compiler/compile/render_dom/wrappers/IfBlock.ts

+129-89
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class IfBlockBranch extends Wrapper {
7474
export default class IfBlockWrapper extends Wrapper {
7575
node: IfBlock;
7676
branches: IfBlockBranch[];
77+
needs_update = false;
7778

7879
var = 'if_block';
7980

@@ -112,10 +113,16 @@ export default class IfBlockWrapper extends Wrapper {
112113
block.add_dependencies(node.expression.dependencies);
113114

114115
if (branch.block.dependencies.size > 0) {
116+
// the condition, or its contents, is dynamic
115117
is_dynamic = true;
116118
block.add_dependencies(branch.block.dependencies);
117119
}
118120

121+
if (branch.dependencies && branch.dependencies.length > 0) {
122+
// the condition itself is dynamic
123+
this.needs_update = true;
124+
}
125+
119126
if (branch.block.has_intros) has_intros = true;
120127
if (branch.block.has_outros) has_outros = true;
121128

@@ -239,15 +246,29 @@ export default class IfBlockWrapper extends Wrapper {
239246
const current_block_type_and = has_else ? '' : `${current_block_type} && `;
240247

241248
/* eslint-disable @typescript-eslint/indent,indent */
242-
block.builders.init.add_block(deindent`
243-
function ${select_block_type}(changed, ctx) {
244-
${this.branches.map(({ dependencies, condition, snippet, block }) => condition
245-
? deindent`
246-
${snippet && `if ((${condition} == null) || ${dependencies.map(n => `changed.${n}`).join(' || ')}) ${condition} = !!(${snippet})`}
247-
if (${condition}) return ${block.name};`
248-
: `return ${block.name};`)}
249-
}
250-
`);
249+
if (this.needs_update) {
250+
block.builders.init.add_block(deindent`
251+
function ${select_block_type}(changed, ctx) {
252+
${this.branches.map(({ dependencies, condition, snippet, block }) => condition
253+
? deindent`
254+
${snippet && (
255+
dependencies.length > 0
256+
? `if ((${condition} == null) || ${dependencies.map(n => `changed.${n}`).join(' || ')}) ${condition} = !!(${snippet})`
257+
: `if (${condition} == null) ${condition} = !!(${snippet})`
258+
)}
259+
if (${condition}) return ${block.name};`
260+
: `return ${block.name};`)}
261+
}
262+
`);
263+
} else {
264+
block.builders.init.add_block(deindent`
265+
function ${select_block_type}(changed, ctx) {
266+
${this.branches.map(({ condition, snippet, block }) => condition
267+
? `if (${snippet || condition}) return ${block.name};`
268+
: `return ${block.name};`)}
269+
}
270+
`);
271+
}
251272
/* eslint-enable @typescript-eslint/indent,indent */
252273

253274
block.builders.init.add_block(deindent`
@@ -261,32 +282,36 @@ export default class IfBlockWrapper extends Wrapper {
261282
`${if_name}${name}.m(${initial_mount_node}, ${anchor_node});`
262283
);
263284

264-
const update_mount_node = this.get_update_mount_node(anchor);
285+
if (this.needs_update) {
286+
const update_mount_node = this.get_update_mount_node(anchor);
265287

266-
const change_block = deindent`
267-
${if_name}${name}.d(1);
268-
${name} = ${current_block_type_and}${current_block_type}(ctx);
269-
if (${name}) {
270-
${name}.c();
271-
${has_transitions && `@transition_in(${name}, 1);`}
272-
${name}.m(${update_mount_node}, ${anchor});
273-
}
274-
`;
275-
276-
if (dynamic) {
277-
block.builders.update.add_block(deindent`
278-
if (${current_block_type} === (${current_block_type} = ${select_block_type}(changed, ctx)) && ${name}) {
279-
${name}.p(changed, ctx);
280-
} else {
281-
${change_block}
282-
}
283-
`);
284-
} else {
285-
block.builders.update.add_block(deindent`
286-
if (${current_block_type} !== (${current_block_type} = ${select_block_type}(changed, ctx))) {
287-
${change_block}
288+
const change_block = deindent`
289+
${if_name}${name}.d(1);
290+
${name} = ${current_block_type_and}${current_block_type}(ctx);
291+
if (${name}) {
292+
${name}.c();
293+
${has_transitions && `@transition_in(${name}, 1);`}
294+
${name}.m(${update_mount_node}, ${anchor});
288295
}
289-
`);
296+
`;
297+
298+
if (dynamic) {
299+
block.builders.update.add_block(deindent`
300+
if (${current_block_type} === (${current_block_type} = ${select_block_type}(changed, ctx)) && ${name}) {
301+
${name}.p(changed, ctx);
302+
} else {
303+
${change_block}
304+
}
305+
`);
306+
} else {
307+
block.builders.update.add_block(deindent`
308+
if (${current_block_type} !== (${current_block_type} = ${select_block_type}(changed, ctx))) {
309+
${change_block}
310+
}
311+
`);
312+
}
313+
} else if (dynamic) {
314+
block.builders.update.add_line(`${name}.p(changed, ctx);`);
290315
}
291316

292317
block.builders.destroy.add_line(`${if_name}${name}.d(${detaching});`);
@@ -323,14 +348,25 @@ export default class IfBlockWrapper extends Wrapper {
323348
324349
var ${if_blocks} = [];
325350
326-
function ${select_block_type}(changed, ctx) {
327-
${this.branches.map(({ dependencies, condition, snippet }, i) => condition
351+
${this.needs_update
328352
? deindent`
329-
${snippet && `if ((${condition} == null) || ${dependencies.map(n => `changed.${n}`).join(' || ')}) ${condition} = !!(${snippet})`}
330-
if (${condition}) return ${String(i)};`
331-
: `return ${i};`)}
332-
${!has_else && `return -1;`}
333-
}
353+
function ${select_block_type}(changed, ctx) {
354+
${this.branches.map(({ dependencies, condition, snippet }, i) => condition
355+
? deindent`
356+
${snippet && `if ((${condition} == null) || ${dependencies.map(n => `changed.${n}`).join(' || ')}) ${condition} = !!(${snippet})`}
357+
if (${condition}) return ${String(i)};`
358+
: `return ${i};`)}
359+
${!has_else && `return -1;`}
360+
}
361+
`
362+
: deindent`
363+
function ${select_block_type}(changed, ctx) {
364+
${this.branches.map(({ condition, snippet }, i) => condition
365+
? `if (${snippet || condition}) return ${String(i)};`
366+
: `return ${i};`)}
367+
${!has_else && `return -1;`}
368+
}
369+
`}
334370
`);
335371
/* eslint-enable @typescript-eslint/indent,indent */
336372

@@ -354,62 +390,66 @@ export default class IfBlockWrapper extends Wrapper {
354390
`${if_current_block_type_index}${if_blocks}[${current_block_type_index}].m(${initial_mount_node}, ${anchor_node});`
355391
);
356392

357-
const update_mount_node = this.get_update_mount_node(anchor);
358-
359-
const destroy_old_block = deindent`
360-
@group_outros();
361-
@transition_out(${if_blocks}[${previous_block_index}], 1, 1, () => {
362-
${if_blocks}[${previous_block_index}] = null;
363-
});
364-
@check_outros();
365-
`;
393+
if (this.needs_update) {
394+
const update_mount_node = this.get_update_mount_node(anchor);
366395

367-
const create_new_block = deindent`
368-
${name} = ${if_blocks}[${current_block_type_index}];
369-
if (!${name}) {
370-
${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](ctx);
371-
${name}.c();
372-
}
373-
${has_transitions && `@transition_in(${name}, 1);`}
374-
${name}.m(${update_mount_node}, ${anchor});
375-
`;
396+
const destroy_old_block = deindent`
397+
@group_outros();
398+
@transition_out(${if_blocks}[${previous_block_index}], 1, 1, () => {
399+
${if_blocks}[${previous_block_index}] = null;
400+
});
401+
@check_outros();
402+
`;
376403

377-
const change_block = has_else
378-
? deindent`
379-
${destroy_old_block}
404+
const create_new_block = deindent`
405+
${name} = ${if_blocks}[${current_block_type_index}];
406+
if (!${name}) {
407+
${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](ctx);
408+
${name}.c();
409+
}
410+
${has_transitions && `@transition_in(${name}, 1);`}
411+
${name}.m(${update_mount_node}, ${anchor});
412+
`;
380413

381-
${create_new_block}
382-
`
383-
: deindent`
384-
if (${name}) {
414+
const change_block = has_else
415+
? deindent`
385416
${destroy_old_block}
386-
}
387417
388-
if (~${current_block_type_index}) {
389418
${create_new_block}
390-
} else {
391-
${name} = null;
392-
}
393-
`;
419+
`
420+
: deindent`
421+
if (${name}) {
422+
${destroy_old_block}
423+
}
394424
395-
if (dynamic) {
396-
block.builders.update.add_block(deindent`
397-
var ${previous_block_index} = ${current_block_type_index};
398-
${current_block_type_index} = ${select_block_type}(changed, ctx);
399-
if (${current_block_type_index} === ${previous_block_index}) {
400-
${if_current_block_type_index}${if_blocks}[${current_block_type_index}].p(changed, ctx);
401-
} else {
402-
${change_block}
403-
}
404-
`);
405-
} else {
406-
block.builders.update.add_block(deindent`
407-
var ${previous_block_index} = ${current_block_type_index};
408-
${current_block_type_index} = ${select_block_type}(changed, ctx);
409-
if (${current_block_type_index} !== ${previous_block_index}) {
410-
${change_block}
411-
}
412-
`);
425+
if (~${current_block_type_index}) {
426+
${create_new_block}
427+
} else {
428+
${name} = null;
429+
}
430+
`;
431+
432+
if (dynamic) {
433+
block.builders.update.add_block(deindent`
434+
var ${previous_block_index} = ${current_block_type_index};
435+
${current_block_type_index} = ${select_block_type}(changed, ctx);
436+
if (${current_block_type_index} === ${previous_block_index}) {
437+
${if_current_block_type_index}${if_blocks}[${current_block_type_index}].p(changed, ctx);
438+
} else {
439+
${change_block}
440+
}
441+
`);
442+
} else {
443+
block.builders.update.add_block(deindent`
444+
var ${previous_block_index} = ${current_block_type_index};
445+
${current_block_type_index} = ${select_block_type}(changed, ctx);
446+
if (${current_block_type_index} !== ${previous_block_index}) {
447+
${change_block}
448+
}
449+
`);
450+
}
451+
} else if (dynamic) {
452+
block.builders.update.add_line(`${name}.p(changed, ctx);`);
413453
}
414454

415455
block.builders.destroy.add_line(deindent`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
eee
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rrr
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
html: 'eee'
3+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script>
2+
import EEE from './EEE.svelte';
3+
import RRR from './RRR.svelte';
4+
</script>
5+
6+
{#if "Eva".startsWith('E')}
7+
<EEE/>
8+
{:else}
9+
<RRR/>
10+
{/if}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
html: 'eee'
3+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{#if "Eva".startsWith('E')}
2+
eee
3+
{:else}
4+
rrr
5+
{/if}

0 commit comments

Comments
 (0)