diff --git a/src/compiler/compile/nodes/shared/Expression.ts b/src/compiler/compile/nodes/shared/Expression.ts index 98fb2f1e3acf..729019222a31 100644 --- a/src/compiler/compile/nodes/shared/Expression.ts +++ b/src/compiler/compile/nodes/shared/Expression.ts @@ -255,8 +255,11 @@ export default class Expression { if (owner.type === 'ConstTag') { walk(node, { - enter(node: Node) { - if (node.type === 'Identifier') { + enter(node: Node, parent: Node) { + if (node.type === 'Identifier' && + // ignore parts of member expressions, + // in obj.key1.key2, Identifiers key1 and key2 should not be replaced + (parent.type !== 'MemberExpression' || parent.property !== node)) { this.replace(block.renderer.reference(node, ctx)); } } diff --git a/test/js/samples/const-tag/expected.js b/test/js/samples/const-tag/expected.js new file mode 100644 index 000000000000..0f3d4bd89fcc --- /dev/null +++ b/test/js/samples/const-tag/expected.js @@ -0,0 +1,120 @@ +/* generated by Svelte vX.Y.Z */ +import { + SvelteComponent, + append, + destroy_block, + detach, + element, + empty, + init, + insert, + noop, + safe_not_equal, + set_data, + text, + update_keyed_each +} from "svelte/internal"; + +function get_each_context(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[2] = list[i].id; + child_ctx[3] = list[i].thing; + const constants_0 = /*otherThings*/ child_ctx[1].find(ot => ot.id.id === /*id*/ child_ctx[2]); + child_ctx[4] = constants_0; + return child_ctx; +} + +// (6:0) {#each things as {id, thing} +function create_each_block(key_1, ctx) { + let div; + let t_value = /*thing*/ ctx[3].name + ""; + let t; + + return { + key: key_1, + first: null, + c() { + div = element("div"); + t = text(t_value); + this.first = div; + }, + m(target, anchor) { + insert(target, div, anchor); + append(div, t); + }, + p(new_ctx, dirty) { + ctx = new_ctx; + if (dirty & /*things*/ 1 && t_value !== (t_value = /*thing*/ ctx[3].name + "")) set_data(t, t_value); + }, + d(detaching) { + if (detaching) detach(div); + } + }; +} + +function create_fragment(ctx) { + let each_blocks = []; + let each_1_lookup = new Map(); + let each_1_anchor; + let each_value = /*things*/ ctx[0]; + const get_key = ctx => /*thing*/ ctx[3].id; + + for (let i = 0; i < each_value.length; i += 1) { + let child_ctx = get_each_context(ctx, each_value, i); + let key = get_key(child_ctx); + each_1_lookup.set(key, each_blocks[i] = create_each_block(key, child_ctx)); + } + + return { + c() { + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + each_1_anchor = empty(); + }, + m(target, anchor) { + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(target, anchor); + } + + insert(target, each_1_anchor, anchor); + }, + p(ctx, [dirty]) { + if (dirty & /*things*/ 1) { + each_value = /*things*/ ctx[0]; + each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, each_1_anchor.parentNode, destroy_block, create_each_block, each_1_anchor, get_each_context); + } + }, + i: noop, + o: noop, + d(detaching) { + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].d(detaching); + } + + if (detaching) detach(each_1_anchor); + } + }; +} + +function instance($$self, $$props, $$invalidate) { + let { things } = $$props; + let { otherThings } = $$props; + + $$self.$$set = $$props => { + if ('things' in $$props) $$invalidate(0, things = $$props.things); + if ('otherThings' in $$props) $$invalidate(1, otherThings = $$props.otherThings); + }; + + return [things, otherThings]; +} + +class Component extends SvelteComponent { + constructor(options) { + super(); + init(this, options, instance, create_fragment, safe_not_equal, { things: 0, otherThings: 1 }); + } +} + +export default Component; diff --git a/test/js/samples/const-tag/input.svelte b/test/js/samples/const-tag/input.svelte new file mode 100644 index 000000000000..67f1931ced46 --- /dev/null +++ b/test/js/samples/const-tag/input.svelte @@ -0,0 +1,9 @@ + + +{#each things as {id, thing} (thing.id)} + {@const otherThing = otherThings.find(ot => ot.id.id === id)} +