From 4285e6d8143c27eaa3fb3d4d27abf44eb1d30d2e Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Tue, 5 Mar 2024 13:51:46 +0100 Subject: [PATCH] fix: prevent snippet children conflict (#10700) closes #10385 --- .changeset/wet-wombats-repeat.md | 5 ++++ packages/svelte/src/compiler/errors.js | 4 ++- .../compiler/phases/2-analyze/validation.js | 18 +++++++++++++ .../src/compiler/phases/3-transform/utils.js | 3 +-- .../snippet-children-conflict/_config.js | 10 ++++++++ .../snippet-children-conflict/main.svelte | 25 +++++++++++++++++++ 6 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 .changeset/wet-wombats-repeat.md create mode 100644 packages/svelte/tests/compiler-errors/samples/snippet-children-conflict/_config.js create mode 100644 packages/svelte/tests/compiler-errors/samples/snippet-children-conflict/main.svelte diff --git a/.changeset/wet-wombats-repeat.md b/.changeset/wet-wombats-repeat.md new file mode 100644 index 0000000000..339f9ffbfa --- /dev/null +++ b/.changeset/wet-wombats-repeat.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: prevent snippet children conflict diff --git a/packages/svelte/src/compiler/errors.js b/packages/svelte/src/compiler/errors.js index 213b689d3e..c31ad4a038 100644 --- a/packages/svelte/src/compiler/errors.js +++ b/packages/svelte/src/compiler/errors.js @@ -296,7 +296,9 @@ const slots = { /** @param {string} name @param {string} component */ 'duplicate-slot-name': (name, component) => `Duplicate slot name '${name}' in <${component}>`, 'invalid-default-slot-content': () => - `Found default slot content alongside an explicit slot="default"` + `Found default slot content alongside an explicit slot="default"`, + 'conflicting-children-snippet': () => + `Cannot use explicit children snippet at the same time as implicit children content. Remove either the non-whitespace content or the children snippet block` }; /** @satisfies {Errors} */ diff --git a/packages/svelte/src/compiler/phases/2-analyze/validation.js b/packages/svelte/src/compiler/phases/2-analyze/validation.js index ddb0d1d584..6bcfd7bb9a 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/validation.js +++ b/packages/svelte/src/compiler/phases/2-analyze/validation.js @@ -521,6 +521,24 @@ const validation = { ); } }, + SnippetBlock(node, { path }) { + if (node.expression.name !== 'children') return; + const parent = path.at(-2); + if (!parent) return; + if ( + parent.type === 'Component' || + parent.type === 'SvelteComponent' || + parent.type === 'SvelteSelf' + ) { + if ( + parent.fragment.nodes.some( + (node) => node.type !== 'SnippetBlock' && (node.type !== 'Text' || node.data.trim()) + ) + ) { + error(node, 'conflicting-children-snippet'); + } + } + }, SvelteHead(node) { const attribute = node.attributes[0]; if (attribute) { diff --git a/packages/svelte/src/compiler/phases/3-transform/utils.js b/packages/svelte/src/compiler/phases/3-transform/utils.js index 3429748e29..de163612a9 100644 --- a/packages/svelte/src/compiler/phases/3-transform/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/utils.js @@ -1,8 +1,7 @@ import { regex_ends_with_whitespaces, regex_not_whitespace, - regex_starts_with_whitespaces, - regex_whitespaces_strict + regex_starts_with_whitespaces } from '../patterns.js'; import * as b from '../../utils/builders.js'; import { walk } from 'zimmerframe'; diff --git a/packages/svelte/tests/compiler-errors/samples/snippet-children-conflict/_config.js b/packages/svelte/tests/compiler-errors/samples/snippet-children-conflict/_config.js new file mode 100644 index 0000000000..3fd2caaeda --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/snippet-children-conflict/_config.js @@ -0,0 +1,10 @@ +import { test } from '../../test'; + +export default test({ + error: { + code: 'conflicting-children-snippet', + message: + 'Cannot use explicit children snippet at the same time as implicit children content. Remove either the non-whitespace content or the children snippet block', + position: [320, 353] + } +}); diff --git a/packages/svelte/tests/compiler-errors/samples/snippet-children-conflict/main.svelte b/packages/svelte/tests/compiler-errors/samples/snippet-children-conflict/main.svelte new file mode 100644 index 0000000000..fcc55f3b9c --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/snippet-children-conflict/main.svelte @@ -0,0 +1,25 @@ + + + + + +