From 93148ee808a6c6d92215a1b059ca1f5e1a8755f3 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 29 Apr 2018 14:15:52 -0400 Subject: [PATCH] deduplicate each block context generation (#1287) --- src/compile/nodes/EachBlock.ts | 36 ++++++++++--------- .../expected-bundle.js | 24 ++++++------- .../each-block-changed-check/expected.js | 24 ++++++------- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/compile/nodes/EachBlock.ts b/src/compile/nodes/EachBlock.ts index f96b330064..a7a061ad58 100644 --- a/src/compile/nodes/EachBlock.ts +++ b/src/compile/nodes/EachBlock.ts @@ -63,7 +63,7 @@ export default class EachBlock extends Node { this.var = block.getUniqueName(`each`); this.iterations = block.getUniqueName(`${this.var}_blocks`); - this.each_context = block.getUniqueName(`${this.var}_context`); + this.get_each_context = block.getUniqueName(`get_${this.var}_context`); const { dependencies } = this.expression; block.addDependencies(dependencies); @@ -88,14 +88,14 @@ export default class EachBlock extends Node { } this.contextProps = [ - `${listName}: ${listName}`, - `${this.context}: ${listName}[#i]`, - `${indexName}: #i` + `${listName}: list`, + `${this.context}: list[i]`, + `${indexName}: i` ]; if (this.destructuredContexts) { for (let i = 0; i < this.destructuredContexts.length; i += 1) { - this.contextProps.push(`${this.destructuredContexts[i]}: ${listName}[#i][${i}]`); + this.contextProps.push(`${this.destructuredContexts[i]}: list[i][${i}]`); } } @@ -162,6 +162,14 @@ export default class EachBlock extends Node { block.builders.init.addLine(`var ${each_block_value} = ${snippet};`); + this.compiler.target.blocks.push(deindent` + function ${this.get_each_context}(ctx, list, i) { + return @assign(@assign({}, ctx), { + ${this.contextProps.join(',\n')} + }); + } + `); + if (this.key) { this.buildKeyed(block, parentNode, parentNodes, snippet, vars); } else { @@ -349,9 +357,7 @@ export default class EachBlock extends Node { var ${iterations} = []; for (var #i = 0; #i < ${each_block_value}.${length}; #i += 1) { - ${iterations}[#i] = ${create_each_block}(#component, @assign(@assign({}, ctx), { - ${this.contextProps.join(',\n')} - })); + ${iterations}[#i] = ${create_each_block}(#component, ${this.get_each_context}(ctx, ${each_block_value}, #i)); } `); @@ -395,24 +401,24 @@ export default class EachBlock extends Node { ? this.block.hasIntroMethod ? deindent` if (${iterations}[#i]) { - ${iterations}[#i].p(changed, ${this.each_context}); + ${iterations}[#i].p(changed, child_ctx); } else { - ${iterations}[#i] = ${create_each_block}(#component, ${this.each_context}); + ${iterations}[#i] = ${create_each_block}(#component, child_ctx); ${iterations}[#i].c(); } ${iterations}[#i].i(${updateMountNode}, ${anchor}); ` : deindent` if (${iterations}[#i]) { - ${iterations}[#i].p(changed, ${this.each_context}); + ${iterations}[#i].p(changed, child_ctx); } else { - ${iterations}[#i] = ${create_each_block}(#component, ${this.each_context}); + ${iterations}[#i] = ${create_each_block}(#component, child_ctx); ${iterations}[#i].c(); ${iterations}[#i].m(${updateMountNode}, ${anchor}); } ` : deindent` - ${iterations}[#i] = ${create_each_block}(#component, ${this.each_context}); + ${iterations}[#i] = ${create_each_block}(#component, child_ctx); ${iterations}[#i].c(); ${iterations}[#i].${mountOrIntro}(${updateMountNode}, ${anchor}); `; @@ -447,9 +453,7 @@ export default class EachBlock extends Node { ${each_block_value} = ${snippet}; for (var #i = ${start}; #i < ${each_block_value}.${length}; #i += 1) { - var ${this.each_context} = @assign(@assign({}, ctx), { - ${this.contextProps.join(',\n')} - }); + const child_ctx = ${this.get_each_context}(ctx, ${each_block_value}, #i); ${forLoopBody} } diff --git a/test/js/samples/each-block-changed-check/expected-bundle.js b/test/js/samples/each-block-changed-check/expected-bundle.js index f4d29ba84a..facaec2b93 100644 --- a/test/js/samples/each-block-changed-check/expected-bundle.js +++ b/test/js/samples/each-block-changed-check/expected-bundle.js @@ -163,11 +163,7 @@ function create_main_fragment(component, ctx) { var each_blocks = []; for (var i = 0; i < each_value.length; i += 1) { - each_blocks[i] = create_each_block(component, assign(assign({}, ctx), { - each_value: each_value, - comment: each_value[i], - i: i - })); + each_blocks[i] = create_each_block(component, get_each_context(ctx, each_value, i)); } return { @@ -196,16 +192,12 @@ function create_main_fragment(component, ctx) { each_value = ctx.comments; for (var i = 0; i < each_value.length; i += 1) { - var each_context = assign(assign({}, ctx), { - each_value: each_value, - comment: each_value[i], - i: i - }); + const child_ctx = get_each_context(ctx, each_value, i); if (each_blocks[i]) { - each_blocks[i].p(changed, each_context); + each_blocks[i].p(changed, child_ctx); } else { - each_blocks[i] = create_each_block(component, each_context); + each_blocks[i] = create_each_block(component, child_ctx); each_blocks[i].c(); each_blocks[i].m(text.parentNode, text); } @@ -303,6 +295,14 @@ function create_each_block(component, ctx) { }; } +function get_each_context(ctx, list, i) { + return assign(assign({}, ctx), { + each_value: list, + comment: list[i], + i: i + }); +} + function SvelteComponent(options) { init(this, options); this._state = assign({}, options.data); diff --git a/test/js/samples/each-block-changed-check/expected.js b/test/js/samples/each-block-changed-check/expected.js index 75dfc20a7d..05af12e226 100644 --- a/test/js/samples/each-block-changed-check/expected.js +++ b/test/js/samples/each-block-changed-check/expected.js @@ -9,11 +9,7 @@ function create_main_fragment(component, ctx) { var each_blocks = []; for (var i = 0; i < each_value.length; i += 1) { - each_blocks[i] = create_each_block(component, assign(assign({}, ctx), { - each_value: each_value, - comment: each_value[i], - i: i - })); + each_blocks[i] = create_each_block(component, get_each_context(ctx, each_value, i)); } return { @@ -42,16 +38,12 @@ function create_main_fragment(component, ctx) { each_value = ctx.comments; for (var i = 0; i < each_value.length; i += 1) { - var each_context = assign(assign({}, ctx), { - each_value: each_value, - comment: each_value[i], - i: i - }); + const child_ctx = get_each_context(ctx, each_value, i); if (each_blocks[i]) { - each_blocks[i].p(changed, each_context); + each_blocks[i].p(changed, child_ctx); } else { - each_blocks[i] = create_each_block(component, each_context); + each_blocks[i] = create_each_block(component, child_ctx); each_blocks[i].c(); each_blocks[i].m(text.parentNode, text); } @@ -149,6 +141,14 @@ function create_each_block(component, ctx) { }; } +function get_each_context(ctx, list, i) { + return assign(assign({}, ctx), { + each_value: list, + comment: list[i], + i: i + }); +} + function SvelteComponent(options) { init(this, options); this._state = assign({}, options.data);