diff --git a/src/compiler/compile/nodes/shared/Expression.ts b/src/compiler/compile/nodes/shared/Expression.ts index c7c66940fd..d4a219418b 100644 --- a/src/compiler/compile/nodes/shared/Expression.ts +++ b/src/compiler/compile/nodes/shared/Expression.ts @@ -198,7 +198,7 @@ export default class Expression { scope = map.get(node); } - if (is_reference(node, parent)) { + if (node.type === 'Identifier' && is_reference(node, parent)) { const { name } = flatten_reference(node); if (scope.has(name)) return; diff --git a/test/js/samples/optional-chaining/expected.js b/test/js/samples/optional-chaining/expected.js new file mode 100644 index 0000000000..a28dc129aa --- /dev/null +++ b/test/js/samples/optional-chaining/expected.js @@ -0,0 +1,189 @@ +/* generated by Svelte vX.Y.Z */ +import { + SvelteComponent, + attr, + create_component, + destroy_component, + detach, + element, + init, + insert, + mount_component, + safe_not_equal, + set_data, + space, + text, + transition_in, + transition_out +} from "svelte/internal"; + +function create_fragment(ctx) { + let t0_value = /*a*/ ctx[0].normal + ""; + let t0; + let t1_value = /*b*/ ctx[1]?.optional + ""; + let t1; + let t2; + let t3_value = /*c*/ ctx[2]["computed"] + ""; + let t3; + let t4_value = /*d*/ ctx[3]?.["computed_optional"] + ""; + let t4; + let t5; + let t6_value = /*e*/ ctx[4]() + ""; + let t6; + let t7_value = /*f*/ ctx[5]?.() + ""; + let t7; + let t8; + let div; + let div_a_value; + let div_b_value; + let div_c_value; + let div_d_value; + let div_e_value; + let div_f_value; + let t9; + let component; + let current; + + component = new /*Component*/ ctx[6]({ + props: { + a: /*a*/ ctx[0].normal, + b: /*b*/ ctx[1]?.optional, + c: /*c*/ ctx[2]["computed"], + d: /*d*/ ctx[3]?.["computed_optional"], + e: /*e*/ ctx[4](), + f: /*f*/ ctx[5]?.() + } + }); + + return { + c() { + t0 = text(t0_value); + t1 = text(t1_value); + t2 = space(); + t3 = text(t3_value); + t4 = text(t4_value); + t5 = space(); + t6 = text(t6_value); + t7 = text(t7_value); + t8 = space(); + div = element("div"); + t9 = space(); + create_component(component.$$.fragment); + attr(div, "a", div_a_value = /*a*/ ctx[0].normal); + attr(div, "b", div_b_value = /*b*/ ctx[1]?.optional); + attr(div, "c", div_c_value = /*c*/ ctx[2]["computed"]); + attr(div, "d", div_d_value = /*d*/ ctx[3]?.["computed_optional"]); + attr(div, "e", div_e_value = /*e*/ ctx[4]()); + attr(div, "f", div_f_value = /*f*/ ctx[5]?.()); + }, + m(target, anchor) { + insert(target, t0, anchor); + insert(target, t1, anchor); + insert(target, t2, anchor); + insert(target, t3, anchor); + insert(target, t4, anchor); + insert(target, t5, anchor); + insert(target, t6, anchor); + insert(target, t7, anchor); + insert(target, t8, anchor); + insert(target, div, anchor); + insert(target, t9, anchor); + mount_component(component, target, anchor); + current = true; + }, + p(ctx, [dirty]) { + if ((!current || dirty & /*a*/ 1) && t0_value !== (t0_value = /*a*/ ctx[0].normal + "")) set_data(t0, t0_value); + if ((!current || dirty & /*b*/ 2) && t1_value !== (t1_value = /*b*/ ctx[1]?.optional + "")) set_data(t1, t1_value); + if ((!current || dirty & /*c*/ 4) && t3_value !== (t3_value = /*c*/ ctx[2]["computed"] + "")) set_data(t3, t3_value); + if ((!current || dirty & /*d*/ 8) && t4_value !== (t4_value = /*d*/ ctx[3]?.["computed_optional"] + "")) set_data(t4, t4_value); + if ((!current || dirty & /*e*/ 16) && t6_value !== (t6_value = /*e*/ ctx[4]() + "")) set_data(t6, t6_value); + if ((!current || dirty & /*f*/ 32) && t7_value !== (t7_value = /*f*/ ctx[5]?.() + "")) set_data(t7, t7_value); + + if (!current || dirty & /*a*/ 1 && div_a_value !== (div_a_value = /*a*/ ctx[0].normal)) { + attr(div, "a", div_a_value); + } + + if (!current || dirty & /*b*/ 2 && div_b_value !== (div_b_value = /*b*/ ctx[1]?.optional)) { + attr(div, "b", div_b_value); + } + + if (!current || dirty & /*c*/ 4 && div_c_value !== (div_c_value = /*c*/ ctx[2]["computed"])) { + attr(div, "c", div_c_value); + } + + if (!current || dirty & /*d*/ 8 && div_d_value !== (div_d_value = /*d*/ ctx[3]?.["computed_optional"])) { + attr(div, "d", div_d_value); + } + + if (!current || dirty & /*e*/ 16 && div_e_value !== (div_e_value = /*e*/ ctx[4]())) { + attr(div, "e", div_e_value); + } + + if (!current || dirty & /*f*/ 32 && div_f_value !== (div_f_value = /*f*/ ctx[5]?.())) { + attr(div, "f", div_f_value); + } + + const component_changes = {}; + if (dirty & /*a*/ 1) component_changes.a = /*a*/ ctx[0].normal; + if (dirty & /*b*/ 2) component_changes.b = /*b*/ ctx[1]?.optional; + if (dirty & /*c*/ 4) component_changes.c = /*c*/ ctx[2]["computed"]; + if (dirty & /*d*/ 8) component_changes.d = /*d*/ ctx[3]?.["computed_optional"]; + if (dirty & /*e*/ 16) component_changes.e = /*e*/ ctx[4](); + if (dirty & /*f*/ 32) component_changes.f = /*f*/ ctx[5]?.(); + component.$set(component_changes); + }, + i(local) { + if (current) return; + transition_in(component.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(component.$$.fragment, local); + current = false; + }, + d(detaching) { + if (detaching) detach(t0); + if (detaching) detach(t1); + if (detaching) detach(t2); + if (detaching) detach(t3); + if (detaching) detach(t4); + if (detaching) detach(t5); + if (detaching) detach(t6); + if (detaching) detach(t7); + if (detaching) detach(t8); + if (detaching) detach(div); + if (detaching) detach(t9); + destroy_component(component, detaching); + } + }; +} + +function instance($$self, $$props, $$invalidate) { + let { a } = $$props; + let { b } = $$props; + let { c } = $$props; + let { d } = $$props; + let { e } = $$props; + let { f } = $$props; + let Component; + + $$self.$set = $$props => { + if ("a" in $$props) $$invalidate(0, a = $$props.a); + if ("b" in $$props) $$invalidate(1, b = $$props.b); + if ("c" in $$props) $$invalidate(2, c = $$props.c); + if ("d" in $$props) $$invalidate(3, d = $$props.d); + if ("e" in $$props) $$invalidate(4, e = $$props.e); + if ("f" in $$props) $$invalidate(5, f = $$props.f); + }; + + return [a, b, c, d, e, f, Component]; +} + +class Component_1 extends SvelteComponent { + constructor(options) { + super(); + init(this, options, instance, create_fragment, safe_not_equal, { a: 0, b: 1, c: 2, d: 3, e: 4, f: 5 }); + } +} + +export default Component_1; \ No newline at end of file diff --git a/test/js/samples/optional-chaining/input.svelte b/test/js/samples/optional-chaining/input.svelte new file mode 100644 index 0000000000..78edf2ca85 --- /dev/null +++ b/test/js/samples/optional-chaining/input.svelte @@ -0,0 +1,31 @@ + + +{a.normal}{b?.optional} +{c['computed']}{d?.['computed_optional']} +{e()}{f?.()} + +
+ + diff --git a/test/parser/samples/action-with-call/output.json b/test/parser/samples/action-with-call/output.json index ccb4011c67..66c569dc5a 100644 --- a/test/parser/samples/action-with-call/output.json +++ b/test/parser/samples/action-with-call/output.json @@ -64,7 +64,8 @@ "value": "tooltip msg", "raw": "'tooltip msg'" } - ] + ], + "optional": false } } ], diff --git a/test/parser/samples/animation/output.json b/test/parser/samples/animation/output.json index 1958ba2817..11195009c8 100644 --- a/test/parser/samples/animation/output.json +++ b/test/parser/samples/animation/output.json @@ -52,10 +52,10 @@ } ], "context": { - "start": 17, - "end": 22, "type": "Identifier", - "name": "thing" + "name": "thing", + "start": 17, + "end": 22 }, "key": { "type": "Identifier", diff --git a/test/parser/samples/await-catch/output.json b/test/parser/samples/await-catch/output.json index c543583018..91862b5366 100644 --- a/test/parser/samples/await-catch/output.json +++ b/test/parser/samples/await-catch/output.json @@ -26,10 +26,10 @@ }, "value": null, "error": { - "start": 47, - "end": 55, "type": "Identifier", - "name": "theError" + "name": "theError", + "start": 47, + "end": 55 }, "pending": { "start": 19, @@ -152,7 +152,8 @@ }, "name": "message" }, - "computed": false + "computed": false, + "optional": false } } ] diff --git a/test/parser/samples/await-then-catch/output.json b/test/parser/samples/await-then-catch/output.json index 8e4b7a4c32..e377d3fa3e 100644 --- a/test/parser/samples/await-then-catch/output.json +++ b/test/parser/samples/await-then-catch/output.json @@ -25,16 +25,16 @@ "name": "thePromise" }, "value": { - "start": 46, - "end": 54, "type": "Identifier", - "name": "theValue" + "name": "theValue", + "start": 46, + "end": 54 }, "error": { - "start": 96, - "end": 104, "type": "Identifier", - "name": "theError" + "name": "theError", + "start": 96, + "end": 104 }, "pending": { "start": 19, @@ -209,7 +209,8 @@ }, "name": "message" }, - "computed": false + "computed": false, + "optional": false } } ] diff --git a/test/parser/samples/dynamic-import/output.json b/test/parser/samples/dynamic-import/output.json index 1e41252afa..ed3d58782d 100644 --- a/test/parser/samples/dynamic-import/output.json +++ b/test/parser/samples/dynamic-import/output.json @@ -275,7 +275,8 @@ }, "name": "then" }, - "computed": false + "computed": false, + "optional": false }, "arguments": [ { @@ -403,7 +404,8 @@ }, "name": "log" }, - "computed": false + "computed": false, + "optional": false }, "arguments": [ { @@ -452,21 +454,25 @@ }, "name": "default" }, - "computed": false + "computed": false, + "optional": false } - ] + ], + "optional": false } } ] } } - ] + ], + "optional": false } } ] } } - ] + ], + "optional": false } } ], diff --git a/test/parser/samples/each-block-else/output.json b/test/parser/samples/each-block-else/output.json index 2720ce5292..622789d177 100644 --- a/test/parser/samples/each-block-else/output.json +++ b/test/parser/samples/each-block-else/output.json @@ -57,10 +57,10 @@ } ], "context": { - "start": 18, - "end": 24, "type": "Identifier", - "name": "animal" + "name": "animal", + "start": 18, + "end": 24 }, "else": { "start": 50, diff --git a/test/parser/samples/each-block-indexed/output.json b/test/parser/samples/each-block-indexed/output.json index 50f2000a36..01b97ffcb4 100644 --- a/test/parser/samples/each-block-indexed/output.json +++ b/test/parser/samples/each-block-indexed/output.json @@ -85,10 +85,10 @@ } ], "context": { - "start": 18, - "end": 24, "type": "Identifier", - "name": "animal" + "name": "animal", + "start": 18, + "end": 24 }, "index": "i" } diff --git a/test/parser/samples/each-block-keyed/output.json b/test/parser/samples/each-block-keyed/output.json index 7dc8681453..6eaf19a82d 100644 --- a/test/parser/samples/each-block-keyed/output.json +++ b/test/parser/samples/each-block-keyed/output.json @@ -57,10 +57,10 @@ } ], "context": { - "start": 16, - "end": 20, "type": "Identifier", - "name": "todo" + "name": "todo", + "start": 16, + "end": 20 }, "key": { "type": "MemberExpression", @@ -108,7 +108,8 @@ }, "name": "id" }, - "computed": false + "computed": false, + "optional": false } } ] diff --git a/test/parser/samples/each-block/output.json b/test/parser/samples/each-block/output.json index 6594fb50a6..82d4455d19 100644 --- a/test/parser/samples/each-block/output.json +++ b/test/parser/samples/each-block/output.json @@ -57,10 +57,10 @@ } ], "context": { - "start": 18, - "end": 24, "type": "Identifier", - "name": "animal" + "name": "animal", + "start": 18, + "end": 24 } } ] diff --git a/test/parser/samples/no-error-if-before-closing/output.json b/test/parser/samples/no-error-if-before-closing/output.json index 708128a42e..f22586b267 100644 --- a/test/parser/samples/no-error-if-before-closing/output.json +++ b/test/parser/samples/no-error-if-before-closing/output.json @@ -116,10 +116,10 @@ "raw": "true" }, "value": { - "start": 97, - "end": 98, "type": "Identifier", - "name": "f" + "name": "f", + "start": 97, + "end": 98 }, "error": null, "pending": { @@ -204,10 +204,10 @@ "raw": "true" }, "value": { - "start": 137, - "end": 138, "type": "Identifier", - "name": "f" + "name": "f", + "start": 137, + "end": 138 }, "error": null, "pending": { diff --git a/test/parser/samples/unusual-identifier/output.json b/test/parser/samples/unusual-identifier/output.json index 76cc82cfd6..3d209d35fe 100644 --- a/test/parser/samples/unusual-identifier/output.json +++ b/test/parser/samples/unusual-identifier/output.json @@ -57,10 +57,10 @@ } ], "context": { - "start": 17, - "end": 19, "type": "Identifier", - "name": "𐊧" + "name": "𐊧", + "start": 17, + "end": 19 } } ]