From 565c7f6ffee84fc90c29425d67e40e97a766d409 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Wed, 15 Nov 2023 11:14:02 +0100 Subject: [PATCH] moved transformation in template.js --- .../compiler/phases/1-parse/state/element.js | 11 +-- .../3-transform/client/visitors/template.js | 37 +++++++++- .../action-with-memberaccess/input.svelte | 1 - .../action-with-memberaccess/output.json | 26 ------- .../directives-with-member-access/_config.js | 3 + .../_expected/client/index.svelte.js | 72 +++++++++++++++++++ .../_expected/server/index.svelte.js | 14 ++++ .../index.svelte | 25 +++++++ 8 files changed, 149 insertions(+), 40 deletions(-) delete mode 100644 packages/svelte/tests/parser-legacy/samples/action-with-memberaccess/input.svelte delete mode 100644 packages/svelte/tests/parser-legacy/samples/action-with-memberaccess/output.json create mode 100644 packages/svelte/tests/snapshot/samples/directives-with-member-access/_config.js create mode 100644 packages/svelte/tests/snapshot/samples/directives-with-member-access/_expected/client/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/directives-with-member-access/_expected/server/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/directives-with-member-access/index.svelte diff --git a/packages/svelte/src/compiler/phases/1-parse/state/element.js b/packages/svelte/src/compiler/phases/1-parse/state/element.js index e0cbf39ad2..d193aeaeb6 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/element.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/element.js @@ -467,16 +467,7 @@ function read_attribute(parser, unique_names) { } if (type) { - const [base_directive_name, ...modifiers] = name.slice(colon_index + 1).split('|'); - - // this allow for accessing members of an object - const splitted_directive = base_directive_name.split('.'); - - let directive_name = splitted_directive.shift() ?? ''; - - for (let new_piece of splitted_directive) { - directive_name += `['${new_piece}']`; - } + const [directive_name, ...modifiers] = name.slice(colon_index + 1).split('|'); if (directive_name === '') { error(start + colon_index + 1, 'empty-directive-name', type); diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index a8ac315934..56c5c512e0 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -74,6 +74,22 @@ function serialize_style_directives(style_directives, element_id, context, is_at } } +/** + * goes from nested.access to nested['access'] + * @param {string} expression + */ +function member_expression_id_to_literal(expression) { + // this allow for accessing members of an object + const splitted_expression = expression.split('.'); + + let new_expression = splitted_expression.shift() ?? ''; + + for (let new_piece of splitted_expression) { + new_expression += `['${new_piece}']`; + } + return new_expression; +} + /** * Serializes each class directive into something like `$.class_toogle(element, class_name, value)` * and adds it either to init or update, depending on whether or not the value or the attributes are dynamic. @@ -1676,7 +1692,16 @@ export const template_visitors = { ? b.literal(null) : b.thunk(/** @type {import('estree').Expression} */ (visit(node.expression))); - state.init.push(b.stmt(b.call('$.animate', state.node, b.id(node.name), expression))); + state.init.push( + b.stmt( + b.call( + '$.animate', + state.node, + b.id(member_expression_id_to_literal(node.name)), + expression + ) + ) + ); }, ClassDirective(node, { state, next }) { error(node, 'INTERNAL', 'Node should have been handled elsewhere'); @@ -1696,7 +1721,7 @@ export const template_visitors = { b.call( type, state.node, - b.id(node.name), + b.id(member_expression_id_to_literal(node.name)), expression, node.modifiers.includes('global') ? b.true : b.false ) @@ -2417,7 +2442,13 @@ export const template_visitors = { /** @type {import('estree').Expression[]} */ const args = [ state.node, - b.arrow(params, b.call(serialize_get_binding(b.id(node.name), state), ...params)) + b.arrow( + params, + b.call( + serialize_get_binding(b.id(member_expression_id_to_literal(node.name)), state), + ...params + ) + ) ]; if (node.expression) { diff --git a/packages/svelte/tests/parser-legacy/samples/action-with-memberaccess/input.svelte b/packages/svelte/tests/parser-legacy/samples/action-with-memberaccess/input.svelte deleted file mode 100644 index 22249d8091..0000000000 --- a/packages/svelte/tests/parser-legacy/samples/action-with-memberaccess/input.svelte +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/svelte/tests/parser-legacy/samples/action-with-memberaccess/output.json b/packages/svelte/tests/parser-legacy/samples/action-with-memberaccess/output.json deleted file mode 100644 index 54db4a21e4..0000000000 --- a/packages/svelte/tests/parser-legacy/samples/action-with-memberaccess/output.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "html": { - "type": "Fragment", - "start": 0, - "end": 25, - "children": [ - { - "type": "Element", - "start": 0, - "end": 25, - "name": "input", - "attributes": [ - { - "start": 7, - "end": 24, - "type": "Action", - "name": "nested['action']", - "modifiers": [], - "expression": null - } - ], - "children": [] - } - ] - } -} diff --git a/packages/svelte/tests/snapshot/samples/directives-with-member-access/_config.js b/packages/svelte/tests/snapshot/samples/directives-with-member-access/_config.js new file mode 100644 index 0000000000..f47bee71df --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/directives-with-member-access/_config.js @@ -0,0 +1,3 @@ +import { test } from '../../test'; + +export default test({}); diff --git a/packages/svelte/tests/snapshot/samples/directives-with-member-access/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/directives-with-member-access/_expected/client/index.svelte.js new file mode 100644 index 0000000000..394f04975c --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/directives-with-member-access/_expected/client/index.svelte.js @@ -0,0 +1,72 @@ +// index.svelte (Svelte VERSION) +// Note: compiler output will change before 5.0 is released! +import "svelte/internal/disclose-version"; +import * as $ from "svelte/internal"; + +var frag = $.template(`
`, true); + +export default function Directives_with_member_access($$anchor, $$props) { + $.push($$props, false); + + const one = () => {}; + const nested = { one }; + const evenmore = { nested }; + + /* Init */ + var fragment = $.open_frag($$anchor, true, frag); + var div = $.child_frag(fragment); + var div_1 = $.sibling($.sibling(div)); + var div_2 = $.sibling($.sibling(div_1)); + var div_3 = $.sibling($.sibling(div_2)); + + $.transition(div_3, one, null, false); + + var div_4 = $.sibling($.sibling(div_3)); + + $.transition(div_4, nested['one'], null, false); + + var div_5 = $.sibling($.sibling(div_4)); + + $.transition(div_5, evenmore['nested']['one'], null, false); + + var div_6 = $.sibling($.sibling(div_5)); + + $.animate(div_6, one, null); + + var div_7 = $.sibling($.sibling(div_6)); + + $.animate(div_7, nested['one'], null); + + var div_8 = $.sibling($.sibling(div_7)); + + $.animate(div_8, evenmore['nested']['one'], null); + + var div_9 = $.sibling($.sibling(div_8)); + + $.in(div_9, one, null, false); + + var div_10 = $.sibling($.sibling(div_9)); + + $.in(div_10, nested['one'], null, false); + + var div_11 = $.sibling($.sibling(div_10)); + + $.in(div_11, evenmore['nested']['one'], null, false); + + var div_12 = $.sibling($.sibling(div_11)); + + $.out(div_12, one, null, false); + + var div_13 = $.sibling($.sibling(div_12)); + + $.out(div_13, nested['one'], null, false); + + var div_14 = $.sibling($.sibling(div_13)); + + $.out(div_14, evenmore['nested']['one'], null, false); + $.action(div, $$node => one($$node)); + $.action(div_1, $$node => nested['one']($$node)); + $.action(div_2, $$node => evenmore['nested']['one']($$node)); + $.close_frag($$anchor, fragment); + $.pop(); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/directives-with-member-access/_expected/server/index.svelte.js b/packages/svelte/tests/snapshot/samples/directives-with-member-access/_expected/server/index.svelte.js new file mode 100644 index 0000000000..fb164e56cd --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/directives-with-member-access/_expected/server/index.svelte.js @@ -0,0 +1,14 @@ +// index.svelte (Svelte VERSION) +// Note: compiler output will change before 5.0 is released! +import * as $ from "svelte/internal/server"; + +export default function Directives_with_member_access($$payload, $$props) { + $.push(false); + + const one = () => {}; + const nested = { one }; + const evenmore = { nested }; + + $$payload.out += `
`; + $.pop(); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/directives-with-member-access/index.svelte b/packages/svelte/tests/snapshot/samples/directives-with-member-access/index.svelte new file mode 100644 index 0000000000..00efd33049 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/directives-with-member-access/index.svelte @@ -0,0 +1,25 @@ + + +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
\ No newline at end of file