From 15650dd7e19c4352dbd63f5a651026ce2ec68ee5 Mon Sep 17 00:00:00 2001 From: "M. Habib Rosyad" Date: Mon, 3 Aug 2020 22:25:33 +0700 Subject: [PATCH] fix each block destructuring can't have default values refered to destructured params --- src/compiler/compile/nodes/shared/Context.ts | 56 ++++++++++++++++++- .../_config.js | 8 +-- .../main.svelte | 4 +- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/compiler/compile/nodes/shared/Context.ts b/src/compiler/compile/nodes/shared/Context.ts index bcc0521ffa..16abef27b2 100644 --- a/src/compiler/compile/nodes/shared/Context.ts +++ b/src/compiler/compile/nodes/shared/Context.ts @@ -25,7 +25,15 @@ export function unpack_destructuring(contexts: Context[], node: Node, modifier: if (element && element.type === 'RestElement') { unpack_destructuring(contexts, element, node => x`${modifier(node)}.slice(${i})` as Node); } else if (element && element.type === 'AssignmentPattern') { - unpack_destructuring(contexts, element.left, node => x`${modifier(node)}[${i}] !== undefined ? ${modifier(node)}[${i}] : ${element.right}` as Node); + const n = contexts.length; + + unpack_destructuring(contexts, element.left, node => { + const alternate = JSON.parse(JSON.stringify(element.right)); + + update_reference(contexts.slice(0, n), node, alternate); + + return x`${modifier(node)}[${i}] !== undefined ? ${modifier(node)}[${i}] : ${alternate.replacement || alternate}` as Node + }); } else { unpack_destructuring(contexts, element, node => x`${modifier(node)}[${i}]` as Node); } @@ -44,9 +52,17 @@ export function unpack_destructuring(contexts: Context[], node: Node, modifier: const key = property.key as Identifier; const value = property.value; - used_properties.push(x`"${(key as Identifier).name}"`); + used_properties.push(x`"${key.name}"`); if (value.type === 'AssignmentPattern') { - unpack_destructuring(contexts, value.left, node => x`${modifier(node)}.${key.name} !== undefined ? ${modifier(node)}.${key.name} : ${value.right}` as Node); + const n = contexts.length; + + unpack_destructuring(contexts, value.left, node => { + const alternate = JSON.parse(JSON.stringify(value.right)); + + update_reference(contexts.slice(0, n), node, alternate); + + return x`${modifier(node)}.${key.name} !== undefined ? ${modifier(node)}.${key.name} : ${alternate.replacement || alternate}` as Node + }); } else { unpack_destructuring(contexts, value, node => x`${modifier(node)}.${key.name}` as Node); } @@ -54,3 +70,37 @@ export function unpack_destructuring(contexts: Context[], node: Node, modifier: }); } } + +function update_reference(contexts: Context[], node: Node, parent: any, property?: any) { + const current_node = (property !== undefined && parent[property] || parent); + + if (!current_node || !contexts.length) return; + + if (current_node.type === 'Identifier') { + contexts.forEach((context) => { + const { key, modifier } = context; + + if (current_node.name === key.name) { + const replacement = modifier(node); + + if (property === undefined) { + current_node.replacement = replacement; + } else { + parent[property] = replacement; + } + } + }); + } else if (current_node.type === 'BinaryExpression') { + update_reference(contexts, node, current_node, 'left'); + update_reference(contexts, node, current_node, 'right'); + } else if (current_node.type === 'CallExpression') { + for (let i = 0; i < current_node.arguments.length; i += 1) { + update_reference(contexts, node, current_node.arguments, i); + } + + update_reference(contexts, node, current_node, 'callee'); + } else if (current_node.type === 'MemberExpression') { + update_reference(contexts, node, current_node, 'object'); + update_reference(contexts, node, current_node, 'property'); + } +} diff --git a/test/runtime/samples/each-block-destructured-default/_config.js b/test/runtime/samples/each-block-destructured-default/_config.js index 133fd68532..68cbb994c4 100644 --- a/test/runtime/samples/each-block-destructured-default/_config.js +++ b/test/runtime/samples/each-block-destructured-default/_config.js @@ -7,16 +7,14 @@ export default { }, html: ` -

raccoon - P. lotor - 25kg

-

eagle - unknown - 5.4kg

+

raccoon - P. lotor - 25kg (55 lb)

+

eagle - unknown - 5.4kg (12 lb)

`, - - test({ assert, component, target }) { component.animalEntries = [{ animal: 'cow', class: 'mammal', species: '‎B. taurus' }]; assert.htmlEqual(target.innerHTML, ` -

cow - ‎B. taurus - 50kg

+

cow - ‎B. taurus - 50kg (110 lb)

`); }, }; diff --git a/test/runtime/samples/each-block-destructured-default/main.svelte b/test/runtime/samples/each-block-destructured-default/main.svelte index a91b45299e..f8140625db 100644 --- a/test/runtime/samples/each-block-destructured-default/main.svelte +++ b/test/runtime/samples/each-block-destructured-default/main.svelte @@ -2,6 +2,6 @@ export let animalEntries; -{#each animalEntries as { animal, species = 'unknown', kilogram: weight = 50 , ...props } } -

{animal} - {species} - {weight}kg

+{#each animalEntries as { animal, species = 'unknown', kilogram: weight = 50, pound = (weight * 2.2).toFixed(0), ...props } } +

{animal} - {species} - {weight}kg ({pound} lb)

{/each}