From 79be365d29b5240ba68f053f1d7e9329e508bb2e Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Fri, 17 Jan 2025 17:04:39 +0100 Subject: [PATCH] fix: error for rune usage in {@const} tag initialization --- .changeset/polite-mirrors-arrive.md | 5 +++++ .../docs/98-reference/.generated/compile-errors.md | 6 ++++++ .../svelte/messages/compile-errors/template.md | 4 ++++ packages/svelte/src/compiler/errors.js | 10 ++++++++++ .../compiler/phases/2-analyze/visitors/ConstTag.js | 8 ++++++++ .../const-tag-invalid-rune-usage/errors.json | 14 ++++++++++++++ .../const-tag-invalid-rune-usage/input.svelte | 3 +++ 7 files changed, 50 insertions(+) create mode 100644 .changeset/polite-mirrors-arrive.md create mode 100644 packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/errors.json create mode 100644 packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/input.svelte diff --git a/.changeset/polite-mirrors-arrive.md b/.changeset/polite-mirrors-arrive.md new file mode 100644 index 0000000000..5e363ffe2c --- /dev/null +++ b/.changeset/polite-mirrors-arrive.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: error for rune usage in {@const} tag initialization diff --git a/documentation/docs/98-reference/.generated/compile-errors.md b/documentation/docs/98-reference/.generated/compile-errors.md index 2fef3bd45d..7882eb1add 100644 --- a/documentation/docs/98-reference/.generated/compile-errors.md +++ b/documentation/docs/98-reference/.generated/compile-errors.md @@ -190,6 +190,12 @@ Cyclical dependency detected: %cycle% `{@const}` must be the immediate child of `{#snippet}`, `{#if}`, `{:else if}`, `{:else}`, `{#each}`, `{:then}`, `{:catch}`, ``, `` ``` +### const_tag_invalid_rune_usage + +``` +Can't use %name% as initialization of a `{@const}` tag +``` + ### constant_assignment ``` diff --git a/packages/svelte/messages/compile-errors/template.md b/packages/svelte/messages/compile-errors/template.md index d061416dbd..55a475d6fc 100644 --- a/packages/svelte/messages/compile-errors/template.md +++ b/packages/svelte/messages/compile-errors/template.md @@ -120,6 +120,10 @@ > `{@const}` must be the immediate child of `{#snippet}`, `{#if}`, `{:else if}`, `{:else}`, `{#each}`, `{:then}`, `{:catch}`, ``, `` +## const_tag_invalid_rune_usage + +> Can't use %name% as initialization of a `{@const}` tag + ## debug_tag_invalid_arguments > {@debug ...} arguments must be identifiers, not arbitrary expressions diff --git a/packages/svelte/src/compiler/errors.js b/packages/svelte/src/compiler/errors.js index 53a6ac6849..8ce56927b0 100644 --- a/packages/svelte/src/compiler/errors.js +++ b/packages/svelte/src/compiler/errors.js @@ -896,6 +896,16 @@ export function const_tag_invalid_placement(node) { e(node, 'const_tag_invalid_placement', `\`{@const}\` must be the immediate child of \`{#snippet}\`, \`{#if}\`, \`{:else if}\`, \`{:else}\`, \`{#each}\`, \`{:then}\`, \`{:catch}\`, \`\`, \`\`\nhttps://svelte.dev/e/const_tag_invalid_placement`); } +/** + * Can't use %name% as initialization of a `{@const}` tag + * @param {null | number | NodeLike} node + * @param {string} name + * @returns {never} + */ +export function const_tag_invalid_rune_usage(node, name) { + e(node, 'const_tag_invalid_rune_usage', `Can't use ${name} as initialization of a \`{@const}\` tag\nhttps://svelte.dev/e/const_tag_invalid_rune_usage`); +} + /** * {@debug ...} arguments must be identifiers, not arbitrary expressions * @param {null | number | NodeLike} node diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/ConstTag.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/ConstTag.js index 3f5e0473c5..2232798c7a 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/ConstTag.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/ConstTag.js @@ -1,6 +1,7 @@ /** @import { AST } from '#compiler' */ /** @import { Context } from '../types' */ import * as e from '../../../errors.js'; +import { get_rune } from '../../scope.js'; import { validate_opening_tag } from './shared/utils.js'; /** @@ -12,6 +13,13 @@ export function ConstTag(node, context) { validate_opening_tag(node, context.state, '@'); } + for (let declaration of node.declaration.declarations) { + const rune = get_rune(declaration.init, context.state.scope); + if (rune) { + e.const_tag_invalid_rune_usage(declaration.init, rune); + } + } + const parent = context.path.at(-1); const grand_parent = context.path.at(-2); diff --git a/packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/errors.json b/packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/errors.json new file mode 100644 index 0000000000..4f297b5589 --- /dev/null +++ b/packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/errors.json @@ -0,0 +1,14 @@ +[ + { + "code": "const_tag_invalid_rune_usage", + "message": "Can't use $derived as initialization of a `{@const}` tag", + "start": { + "line": 2, + "column": 15 + }, + "end": { + "line": 2, + "column": 26 + } + } +] diff --git a/packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/input.svelte b/packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/input.svelte new file mode 100644 index 0000000000..a056058cc5 --- /dev/null +++ b/packages/svelte/tests/validator/samples/const-tag-invalid-rune-usage/input.svelte @@ -0,0 +1,3 @@ +{#snippet test()} + {@const der = $derived(0)} +{/snippet} \ No newline at end of file