From 519be6e5957f3aaf8555dca4e62b551ccbbe9814 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 15 Nov 2023 09:24:37 -0500 Subject: [PATCH 1/3] move snapshot test to a runtime test --- .../directives-with-member-access/_config.js | 5 + .../main.svelte} | 14 ++- .../directives-with-member-access/_config.js | 5 - .../_expected/client/index.svelte.js | 108 ------------------ packages/svelte/tests/snapshot/test.ts | 4 - 5 files changed, 15 insertions(+), 121 deletions(-) create mode 100644 packages/svelte/tests/runtime-runes/samples/directives-with-member-access/_config.js rename packages/svelte/tests/{snapshot/samples/directives-with-member-access/index.svelte => runtime-runes/samples/directives-with-member-access/main.svelte} (65%) delete mode 100644 packages/svelte/tests/snapshot/samples/directives-with-member-access/_config.js delete mode 100644 packages/svelte/tests/snapshot/samples/directives-with-member-access/_expected/client/index.svelte.js diff --git a/packages/svelte/tests/runtime-runes/samples/directives-with-member-access/_config.js b/packages/svelte/tests/runtime-runes/samples/directives-with-member-access/_config.js new file mode 100644 index 000000000000..29a23b32246e --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/directives-with-member-access/_config.js @@ -0,0 +1,5 @@ +import { test } from '../../test'; + +// no need to compare the rendered HTML — we only care +// that the generated code is valid +export default test({}); diff --git a/packages/svelte/tests/snapshot/samples/directives-with-member-access/index.svelte b/packages/svelte/tests/runtime-runes/samples/directives-with-member-access/main.svelte similarity index 65% rename from packages/svelte/tests/snapshot/samples/directives-with-member-access/index.svelte rename to packages/svelte/tests/runtime-runes/samples/directives-with-member-access/main.svelte index b5487aae33cb..0086f247c851 100644 --- a/packages/svelte/tests/snapshot/samples/directives-with-member-access/index.svelte +++ b/packages/svelte/tests/runtime-runes/samples/directives-with-member-access/main.svelte @@ -1,7 +1,11 @@
@@ -24,6 +28,8 @@
+
@@ -37,4 +43,4 @@
-
\ No newline at end of file +
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 deleted file mode 100644 index 43e2501b6ef0..000000000000 --- a/packages/svelte/tests/snapshot/samples/directives-with-member-access/_config.js +++ /dev/null @@ -1,5 +0,0 @@ -import { test } from '../../test'; - -export default test({ - skip_if_ssr: true -}); 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 deleted file mode 100644 index 3c60a11a7688..000000000000 --- a/packages/svelte/tests/snapshot/samples/directives-with-member-access/_expected/client/index.svelte.js +++ /dev/null @@ -1,108 +0,0 @@ -// 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, "with-string": 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); - - var div_15 = $.sibling($.sibling(div_14)); - var div_16 = $.sibling($.sibling(div_15)); - var div_17 = $.sibling($.sibling(div_16)); - - $.transition(div_17, nested['with-string'], null, false); - - var div_18 = $.sibling($.sibling(div_17)); - - $.transition(div_18, evenmore['nested']['with-string'], null, false); - - var div_19 = $.sibling($.sibling(div_18)); - - $.animate(div_19, nested['with-string'], null); - - var div_20 = $.sibling($.sibling(div_19)); - - $.animate(div_20, evenmore['nested']['with-string'], null); - - var div_21 = $.sibling($.sibling(div_20)); - - $.in(div_21, nested['with-string'], null, false); - - var div_22 = $.sibling($.sibling(div_21)); - - $.in(div_22, evenmore['nested']['with-string'], null, false); - - var div_23 = $.sibling($.sibling(div_22)); - - $.out(div_23, nested['with-string'], null, false); - - var div_24 = $.sibling($.sibling(div_23)); - - $.out(div_24, evenmore['nested']['with-string'], null, false); - $.action(div, $$node => one($$node)); - $.action(div_1, $$node => nested['one']($$node)); - $.action(div_2, $$node => evenmore['nested']['one']($$node)); - $.action(div_15, $$node => nested['with-string']($$node)); - $.action(div_16, $$node => evenmore['nested']['with-string']($$node)); - $.close_frag($$anchor, fragment); - $.pop(); -} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/test.ts b/packages/svelte/tests/snapshot/test.ts index 495af0df443f..fcac508cfa17 100644 --- a/packages/svelte/tests/snapshot/test.ts +++ b/packages/svelte/tests/snapshot/test.ts @@ -7,14 +7,10 @@ import { VERSION } from 'svelte/compiler'; interface SnapshotTest extends BaseTest { compileOptions?: Partial; - skip_if_ssr?: boolean; } const { test, run } = suite(async (config, cwd) => { compile_directory(cwd, 'client', config.compileOptions); - if (!config.skip_if_ssr) { - compile_directory(cwd, 'server', config.compileOptions); - } // run `UPDATE_SNAPSHOTS=true pnpm test snapshot` to update snapshot tests if (process.env.UPDATE_SNAPSHOTS) { From 7c92782f2d2270af5f1091ed2839017ade4ef722 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 15 Nov 2023 09:46:52 -0500 Subject: [PATCH 2/3] handle dynamic cases --- .../3-transform/client/visitors/template.js | 28 +++++++----- .../directives-with-member-access/main.svelte | 45 ++++--------------- 2 files changed, 26 insertions(+), 47 deletions(-) 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 56c5c512e00a..942bfab8c6a1 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 @@ -34,6 +34,7 @@ import { EACH_ITEM_REACTIVE, EACH_KEYED } from '../../../../../constants.js'; +import { regex_is_valid_identifier } from '../../../patterns.js'; /** * Serializes each style directive into something like `$.style(element, style_property, value)` @@ -75,19 +76,24 @@ function serialize_style_directives(style_directives, element_id, context, is_at } /** - * goes from nested.access to nested['access'] - * @param {string} expression + * For unfortunate legacy reasons, directive names can look like this `use:a.b-c` + * This turns that string into a member expression + * @param {string} name */ -function member_expression_id_to_literal(expression) { +function parse_directive_name(name) { // this allow for accessing members of an object - const splitted_expression = expression.split('.'); + const parts = name.split('.'); + let part = /** @type {string} */ (parts.shift()); - let new_expression = splitted_expression.shift() ?? ''; + /** @type {import('estree').Identifier | import('estree').MemberExpression} */ + let expression = b.id(part); - for (let new_piece of splitted_expression) { - new_expression += `['${new_piece}']`; + while ((part = /** @type {string} */ (parts.shift()))) { + const computed = !regex_is_valid_identifier.test(part); + expression = b.member(expression, computed ? b.literal(part) : b.id(part), computed); } - return new_expression; + + return expression; } /** @@ -1697,7 +1703,7 @@ export const template_visitors = { b.call( '$.animate', state.node, - b.id(member_expression_id_to_literal(node.name)), + /** @type {import('estree').Expression} */ (visit(parse_directive_name(node.name))), expression ) ) @@ -1721,7 +1727,7 @@ export const template_visitors = { b.call( type, state.node, - b.id(member_expression_id_to_literal(node.name)), + /** @type {import('estree').Expression} */ (visit(parse_directive_name(node.name))), expression, node.modifiers.includes('global') ? b.true : b.false ) @@ -2445,7 +2451,7 @@ export const template_visitors = { b.arrow( params, b.call( - serialize_get_binding(b.id(member_expression_id_to_literal(node.name)), state), + /** @type {import('estree').Expression} */ (visit(parse_directive_name(node.name))), ...params ) ) diff --git a/packages/svelte/tests/runtime-runes/samples/directives-with-member-access/main.svelte b/packages/svelte/tests/runtime-runes/samples/directives-with-member-access/main.svelte index 0086f247c851..66eb1eed36a7 100644 --- a/packages/svelte/tests/runtime-runes/samples/directives-with-member-access/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/directives-with-member-access/main.svelte @@ -3,44 +3,17 @@ * @param {Element} [node] * @param {any} [options] */ - const one = (node, options) => ({}); - const nested = { one, "with-string": one }; - const evenmore = { nested }; - - -
-
-
- -
-
-
+ const fn = (node, options) => ({}); -
-
-
+ let a = { b: { 'c-d': fn } }; -
-
-
- -
-
-
+ let directive = $derived(a); + -
-
- -
-
- -
-
- -
-
- -
-
+
+
+
+
+
From becfcbc6bf258e3cd297fec29027b339902258a2 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 15 Nov 2023 11:08:38 -0500 Subject: [PATCH 3/3] huh --- packages/svelte/tests/snapshot/test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/svelte/tests/snapshot/test.ts b/packages/svelte/tests/snapshot/test.ts index fcac508cfa17..26f3a1a1b7ee 100644 --- a/packages/svelte/tests/snapshot/test.ts +++ b/packages/svelte/tests/snapshot/test.ts @@ -11,6 +11,7 @@ interface SnapshotTest extends BaseTest { const { test, run } = suite(async (config, cwd) => { compile_directory(cwd, 'client', config.compileOptions); + compile_directory(cwd, 'server', config.compileOptions); // run `UPDATE_SNAPSHOTS=true pnpm test snapshot` to update snapshot tests if (process.env.UPDATE_SNAPSHOTS) {