From 36ed1a78be6b532eb794166bbc2157abd21f9c4d Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 1 Sep 2026 12:12:59 +0100 Subject: [PATCH 1/5] chore: use message-box for message processing --- packages/svelte/package.json | 1 + .../svelte/scripts/process-messages/index.js | 353 +------ .../templates/client-errors.js | 8 +- .../templates/client-warnings.js | 8 +- .../templates/compile-errors.js | 8 +- .../templates/compile-warnings.js | 8 +- .../templates/server-errors.js | 8 +- .../templates/server-warnings.js | 8 +- .../templates/shared-errors.js | 8 +- .../templates/shared-warnings.js | 8 +- packages/svelte/src/compiler/errors.js | 981 ++++++++++-------- .../src/compiler/phases/1-parse/acorn.js | 2 +- .../src/compiler/phases/1-parse/index.js | 6 +- .../compiler/phases/1-parse/read/options.js | 10 +- .../compiler/phases/1-parse/read/script.js | 6 +- .../phases/1-parse/remove_typescript_nodes.js | 19 +- .../compiler/phases/1-parse/state/element.js | 33 +- .../src/compiler/phases/1-parse/state/tag.js | 10 +- .../compiler/phases/1-parse/utils/bracket.js | 2 +- .../phases/2-analyze/css/css-analyze.js | 2 +- .../compiler/phases/2-analyze/css/css-warn.js | 2 +- .../src/compiler/phases/2-analyze/index.js | 25 +- .../phases/2-analyze/visitors/AwaitBlock.js | 4 +- .../2-analyze/visitors/BindDirective.js | 48 +- .../2-analyze/visitors/CallExpression.js | 36 +- .../phases/2-analyze/visitors/ClassBody.js | 10 +- .../2-analyze/visitors/DeclarationTag.js | 2 +- .../phases/2-analyze/visitors/EachBlock.js | 2 +- .../2-analyze/visitors/ExpressionTag.js | 2 +- .../phases/2-analyze/visitors/Identifier.js | 12 +- .../2-analyze/visitors/ImportDeclaration.js | 2 +- .../phases/2-analyze/visitors/OnDirective.js | 2 +- .../2-analyze/visitors/RegularElement.js | 12 +- .../phases/2-analyze/visitors/SnippetBlock.js | 4 +- .../2-analyze/visitors/SvelteDocument.js | 2 +- .../phases/2-analyze/visitors/SvelteSelf.js | 2 +- .../phases/2-analyze/visitors/SvelteWindow.js | 2 +- .../phases/2-analyze/visitors/Text.js | 2 +- .../2-analyze/visitors/VariableDeclarator.js | 2 +- .../2-analyze/visitors/shared/a11y/index.js | 114 +- .../2-analyze/visitors/shared/attribute.js | 2 +- .../2-analyze/visitors/shared/element.js | 22 +- .../visitors/shared/special-element.js | 2 +- .../phases/2-analyze/visitors/shared/utils.js | 13 +- .../src/compiler/phases/3-transform/utils.js | 2 +- packages/svelte/src/compiler/phases/scope.js | 2 +- .../compiler/utils/extract_svelte_ignore.js | 4 +- .../svelte/src/compiler/validate-options.js | 6 +- packages/svelte/src/compiler/warnings.js | 497 ++++----- packages/svelte/src/index-client.js | 16 +- packages/svelte/src/index-server.js | 8 +- .../svelte/src/internal/client/dev/assign.js | 5 +- .../src/internal/client/dev/console-log.js | 2 +- .../src/internal/client/dev/equality.js | 10 +- .../svelte/src/internal/client/dev/legacy.js | 7 +- .../src/internal/client/dev/ownership.js | 14 +- .../src/internal/client/dom/blocks/each.js | 6 +- .../src/internal/client/dom/blocks/html.js | 3 +- .../client/dom/elements/attributes.js | 8 +- .../internal/client/dom/elements/events.js | 2 +- packages/svelte/src/internal/client/errors.js | 292 +++--- .../svelte/src/internal/client/hydratable.js | 6 +- .../src/internal/client/reactivity/batch.js | 2 +- .../internal/client/reactivity/deriveds.js | 5 +- .../src/internal/client/reactivity/effects.js | 4 +- .../src/internal/client/reactivity/props.js | 4 +- .../svelte/src/internal/client/runtime.js | 2 +- .../svelte/src/internal/client/validate.js | 2 +- .../svelte/src/internal/client/warnings.js | 249 +++-- packages/svelte/src/internal/server/errors.js | 98 +- .../svelte/src/internal/server/hydratable.js | 10 +- packages/svelte/src/internal/server/index.js | 2 +- .../svelte/src/internal/server/renderer.js | 5 +- .../svelte/src/internal/server/warnings.js | 19 +- packages/svelte/src/internal/shared/clone.js | 2 +- .../svelte/src/internal/shared/context.js | 2 +- packages/svelte/src/internal/shared/dev.js | 2 +- packages/svelte/src/internal/shared/errors.js | 96 +- .../svelte/src/internal/shared/validate.js | 4 +- .../svelte/src/internal/shared/warnings.js | 30 +- packages/svelte/src/legacy/legacy-client.js | 4 +- packages/svelte/src/transition/index.js | 2 +- pnpm-lock.yaml | 8 + 83 files changed, 1557 insertions(+), 1700 deletions(-) diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 53e5516bf6..3596345da6 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -157,6 +157,7 @@ "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-virtual": "^3.0.2", + "@sveltejs/message-box": "^1.1.0", "@types/aria-query": "^5.0.4", "@types/node": "^20.11.5", "@types/trusted-types": "^2.0.7", diff --git a/packages/svelte/scripts/process-messages/index.js b/packages/svelte/scripts/process-messages/index.js index c8d7418db4..ef817b8f7d 100644 --- a/packages/svelte/scripts/process-messages/index.js +++ b/packages/svelte/scripts/process-messages/index.js @@ -1,21 +1,16 @@ -/** @import { Node } from 'esrap/languages/ts' */ -/** @import * as ESTree from 'estree' */ -/** @import { AST } from 'svelte/compiler' */ +/** @import { Message } from '@sveltejs/message-box' */ // @ts-check import process from 'node:process'; import fs from 'node:fs'; -import * as acorn from 'acorn'; -import { walk } from 'zimmerframe'; -import * as esrap from 'esrap'; -import ts from 'esrap/languages/ts'; +import { parse, render } from '@sveltejs/message-box'; const DIR = '../../documentation/docs/98-reference/.generated'; const watch = process.argv.includes('-w'); function run() { - /** @type {Record>} */ + /** @type {Record>} */ const messages = {}; const seen = new Set(); @@ -34,35 +29,22 @@ function run() { .readFileSync(`messages/${category}/${file}`, 'utf-8') .replace(/\r\n/g, '\n'); - const sorted = []; - - for (const match of markdown.matchAll(/## ([\w]+)\n\n([^]+?)(?=$|\n\n## )/g)) { - const [_, code, text] = match; - - if (seen.has(code)) { - throw new Error(`Duplicate message code ${category}/${code}`); - } - - sorted.push({ code, _ }); - - const sections = text.trim().split('\n\n'); - const details = []; - - while (!sections[sections.length - 1].startsWith('> ')) { - details.unshift(/** @type {string} */ (sections.pop())); - } - - if (sections.length === 0) { - throw new Error('No message text'); + for (const message of parse(markdown)) { + if (seen.has(message.code)) { + throw new Error(`Duplicate message code ${category}/${message.code}`); } - seen.add(code); - messages[category][code] = { - messages: sections.map((section) => section.replace(/^> /gm, '').replace(/^>\n/gm, '\n')), - details: details.join('\n\n') - }; + seen.add(message.code); + messages[category][message.code] = message; } + const sorted = Array.from( + markdown.matchAll(/## ([\w]+)\n\n([^]+?)(?=$|\n\n## )/g), + ([_, code]) => ({ + code, + _ + }) + ); sorted.sort((a, b) => (a.code < b.code ? -1 : 1)); fs.writeFileSync( @@ -75,11 +57,8 @@ function run() { `${DIR}/${category}.md`, '\n\n' + Object.entries(messages[category]) - .map(([code, { messages, details }]) => { - const chunks = [ - `### ${code}`, - ...messages.map((message) => '```\n' + message + '\n```') - ]; + .map(([code, { variants, details }]) => { + const chunks = [`### ${code}`, ...variants.map(({ text }) => '```\n' + text + '\n```')]; if (details) { chunks.push(details); @@ -101,296 +80,28 @@ function run() { const source = fs .readFileSync(new URL(`./templates/${name}.js`, import.meta.url), 'utf-8') .replace(/\r\n/g, '\n'); + const marker = '/**\n * DESCRIPTION'; + const index = source.lastIndexOf(marker); - /** @type {AST.JSComment[]} */ - const comments = []; - - let ast = /** @type {ESTree.Node} */ ( - /** @type {unknown} */ ( - acorn.parse(source, { - ecmaVersion: 'latest', - sourceType: 'module', - locations: true, - onComment: comments - }) - ) - ); - - comments.forEach((comment) => { - if (comment.type === 'Block') { - comment.value = comment.value.replace(/^\t+/gm, ''); - } - }); - - ast = walk(ast, null, { - Identifier(node, context) { - if (node.name === 'CODES') { - /** @type {ESTree.ArrayExpression} */ - const array = { - type: 'ArrayExpression', - elements: Object.keys(messages[name]).map((code) => ({ - type: 'Literal', - value: code - })) - }; - - return array; - } - } - }); - - const body = /** @type {ESTree.Program} */ (ast).body; + if (index === -1) throw new Error(`missing message template in ${name}.js`); const category = messages[name]; - - // find the `export function CODE` node - const index = body.findIndex((node) => { - if ( - node.type === 'ExportNamedDeclaration' && - node.declaration && - node.declaration.type === 'FunctionDeclaration' - ) { - return node.declaration.id.name === 'CODE'; - } - }); - - if (index === -1) throw new Error(`missing export function CODE in ${name}.js`); - - const template_node = body[index]; - body.splice(index, 1); - - const jsdoc = /** @type {AST.JSComment} */ ( - comments.findLast((comment) => comment.start < /** @type {number} */ (template_node.start)) - ); - - const printed = esrap.print( - /** @type {Node} */ (ast), - ts({ - comments: comments.filter((comment) => comment !== jsdoc) - }) - ); - - for (const code in category) { - const { messages } = category[code]; - /** @type {string[]} */ - const vars = []; - - const group = messages.map((text, i) => { - for (const match of text.matchAll(/%(\w+)%/g)) { - const name = match[1]; - if (!vars.includes(name)) { - vars.push(match[1]); - } - } - - return { - text, - vars: vars.slice() - }; - }); - - /** @type {ESTree.Expression} */ - let message = { type: 'Literal', value: '' }; - let prev_vars; - - for (let i = 0; i < group.length; i += 1) { - const { text, vars } = group[i]; - - if (vars.length === 0) { - message = { - type: 'Literal', - value: text - }; - prev_vars = vars; - continue; - } - - const parts = text.split(/(%\w+%)/); - - /** @type {ESTree.Expression[]} */ - const expressions = []; - - /** @type {ESTree.TemplateElement[]} */ - const quasis = []; - - for (let i = 0; i < parts.length; i += 1) { - const part = parts[i]; - if (i % 2 === 0) { - const str = part.replace(/(`|\${)/g, '\\$1'); - quasis.push({ - type: 'TemplateElement', - value: { raw: str, cooked: str }, - tail: i === parts.length - 1 - }); - } else { - expressions.push({ - type: 'Identifier', - name: part.slice(1, -1) - }); - } - } - - /** @type {ESTree.Expression} */ - const expression = { - type: 'TemplateLiteral', - expressions, - quasis - }; - - if (prev_vars) { - if (vars.length === prev_vars.length) { - throw new Error('Message overloads must have new parameters'); - } - - message = { - type: 'ConditionalExpression', - test: { - type: 'Identifier', - name: vars[prev_vars.length] - }, - consequent: expression, - alternate: message - }; - } else { - message = expression; - } - - prev_vars = vars; - } - - const clone = /** @type {ESTree.Statement} */ ( - walk(/** @type {ESTree.Node} */ (template_node), null, { - FunctionDeclaration(node, context) { - if (node.id.name !== 'CODE') return; - - const params = []; - - for (const param of node.params) { - if (param.type === 'Identifier' && param.name === 'PARAMETER') { - params.push(...vars.map((name) => ({ type: 'Identifier', name }))); - } else { - params.push(param); - } - } - - return /** @type {ESTree.FunctionDeclaration} */ ({ - .../** @type {ESTree.FunctionDeclaration} */ (context.next()), - params, - id: { - ...node.id, - name: code - } - }); - }, - TemplateLiteral(node, context) { - /** @type {ESTree.TemplateElement} */ - let quasi = { - type: 'TemplateElement', - value: { - ...node.quasis[0].value - }, - tail: node.quasis[0].tail - }; - - /** @type {ESTree.TemplateLiteral} */ - let out = { - type: 'TemplateLiteral', - quasis: [quasi], - expressions: [] - }; - - for (let i = 0; i < node.expressions.length; i += 1) { - const q = structuredClone(node.quasis[i + 1]); - const e = node.expressions[i]; - - if (e.type === 'Literal' && e.value === 'CODE') { - quasi.value.raw += code + q.value.raw; - continue; - } - - if (e.type === 'Identifier' && e.name === 'MESSAGE') { - if (message.type === 'Literal') { - const str = /** @type {string} */ (message.value).replace(/(`|\${)/g, '\\$1'); - quasi.value.raw += str + q.value.raw; - continue; - } - - if (message.type === 'TemplateLiteral') { - const m = structuredClone(message); - quasi.value.raw += m.quasis[0].value.raw; - out.quasis.push(...m.quasis.slice(1)); - out.expressions.push(...m.expressions); - quasi = m.quasis[m.quasis.length - 1]; - quasi.value.raw += q.value.raw; - continue; - } - } - - out.quasis.push((quasi = q)); - out.expressions.push(/** @type {ESTree.Expression} */ (context.visit(e))); - } - - return out; - }, - Literal(node) { - if (node.value === 'CODE') { - return { - type: 'Literal', - value: code - }; - } - }, - Identifier(node) { - if (node.name !== 'MESSAGE') return; - return message; - } - }) - ); - - const jsdoc_clone = { - ...jsdoc, - value: /** @type {string} */ (jsdoc.value) - .split('\n') - .map((line) => { - if (line === ' * MESSAGE') { - return messages[messages.length - 1] - .split('\n') - .map((line) => ` * ${line}`) - .join('\n'); - } - - if (line.includes('PARAMETER')) { - return vars - .map((name, i) => { - const optional = i >= group[0].vars.length; - - return optional - ? ` * @param {string | undefined | null} [${name}]` - : ` * @param {string} ${name}`; - }) - .join('\n'); - } - - return line; - }) - .filter((x) => x !== '') - .join('\n') - }; - - const block = esrap.print( - /** @type {ESTree.Program} */ ({ ...ast, body: [clone] }), - ts({ comments: [jsdoc_clone] }) - ).code; - - printed.code += `\n\n${block}`; - - body.push(clone); - } + const codes = `[\n${Object.keys(category) + .map((code) => `\t'${code}'`) + .join(',\n')}\n]`; + const preamble = source.slice(0, index).trimEnd().replace('CODES', codes); + const template = source.slice(index).trim(); + const output = Object.values(category) + .map((message) => render(message, template)) + .join('\n\n'); fs.writeFileSync( dest, `/* This file is generated by scripts/process-messages/index.js. Do not edit! */\n\n` + - printed.code, + preamble + + '\n\n' + + output + + '\n', 'utf-8' ); } diff --git a/packages/svelte/scripts/process-messages/templates/client-errors.js b/packages/svelte/scripts/process-messages/templates/client-errors.js index ef749b4ba3..563e7e77d5 100644 --- a/packages/svelte/scripts/process-messages/templates/client-errors.js +++ b/packages/svelte/scripts/process-messages/templates/client-errors.js @@ -3,13 +3,13 @@ import { DEV } from 'esm-env'; export * from '../shared/errors.js'; /** - * MESSAGE - * @param {string} PARAMETER + * DESCRIPTION + * @param {VALUES} values * @returns {never} */ -export function CODE(PARAMETER) { +export function CODE(values) { if (DEV) { - const error = new Error(`${'CODE'}\n${MESSAGE}\nhttps://svelte.dev/e/${'CODE'}`); + const error = new Error(`${'CODE'}\n${MESSAGE(values)}\nhttps://svelte.dev/e/${'CODE'}`); error.name = 'Svelte error'; throw error; } else { diff --git a/packages/svelte/scripts/process-messages/templates/client-warnings.js b/packages/svelte/scripts/process-messages/templates/client-warnings.js index 8a9b87b760..7b4a6821fe 100644 --- a/packages/svelte/scripts/process-messages/templates/client-warnings.js +++ b/packages/svelte/scripts/process-messages/templates/client-warnings.js @@ -4,13 +4,13 @@ var bold = 'font-weight: bold'; var normal = 'font-weight: normal'; /** - * MESSAGE - * @param {string} PARAMETER + * DESCRIPTION + * @param {VALUES} values */ -export function CODE(PARAMETER) { +export function CODE(values) { if (DEV) { console.warn( - `%c[svelte] ${'CODE'}\n%c${MESSAGE}\nhttps://svelte.dev/e/${'CODE'}`, + `%c[svelte] ${'CODE'}\n%c${MESSAGE(values)}\nhttps://svelte.dev/e/${'CODE'}`, bold, normal ); diff --git a/packages/svelte/scripts/process-messages/templates/compile-errors.js b/packages/svelte/scripts/process-messages/templates/compile-errors.js index 445f5d14e6..7b1bf63c4a 100644 --- a/packages/svelte/scripts/process-messages/templates/compile-errors.js +++ b/packages/svelte/scripts/process-messages/templates/compile-errors.js @@ -50,11 +50,11 @@ function e(node, code, message) { } /** - * MESSAGE + * DESCRIPTION * @param {null | number | NodeLike} node - * @param {string} PARAMETER + * @param {VALUES} values * @returns {never} */ -export function CODE(node, PARAMETER) { - e(node, 'CODE', `${MESSAGE}\nhttps://svelte.dev/e/${'CODE'}`); +export function CODE(node, values) { + e(node, 'CODE', `${MESSAGE(values)}\nhttps://svelte.dev/e/${'CODE'}`); } diff --git a/packages/svelte/scripts/process-messages/templates/compile-warnings.js b/packages/svelte/scripts/process-messages/templates/compile-warnings.js index e0c970c664..768f9c6eb3 100644 --- a/packages/svelte/scripts/process-messages/templates/compile-warnings.js +++ b/packages/svelte/scripts/process-messages/templates/compile-warnings.js @@ -42,10 +42,10 @@ function w(node, code, message) { export const codes = CODES; /** - * MESSAGE + * DESCRIPTION * @param {null | NodeLike} node - * @param {string} PARAMETER + * @param {VALUES} values */ -export function CODE(node, PARAMETER) { - w(node, 'CODE', `${MESSAGE}\nhttps://svelte.dev/e/${'CODE'}`); +export function CODE(node, values) { + w(node, 'CODE', `${MESSAGE(values)}\nhttps://svelte.dev/e/${'CODE'}`); } diff --git a/packages/svelte/scripts/process-messages/templates/server-errors.js b/packages/svelte/scripts/process-messages/templates/server-errors.js index 0bbe801abc..83b8d87616 100644 --- a/packages/svelte/scripts/process-messages/templates/server-errors.js +++ b/packages/svelte/scripts/process-messages/templates/server-errors.js @@ -1,12 +1,12 @@ export * from '../shared/errors.js'; /** - * MESSAGE - * @param {string} PARAMETER + * DESCRIPTION + * @param {VALUES} values * @returns {never} */ -export function CODE(PARAMETER) { - const error = new Error(`${'CODE'}\n${MESSAGE}\nhttps://svelte.dev/e/${'CODE'}`); +export function CODE(values) { + const error = new Error(`${'CODE'}\n${MESSAGE(values)}\nhttps://svelte.dev/e/${'CODE'}`); error.name = 'Svelte error'; throw error; } diff --git a/packages/svelte/scripts/process-messages/templates/server-warnings.js b/packages/svelte/scripts/process-messages/templates/server-warnings.js index 8a9b87b760..7b4a6821fe 100644 --- a/packages/svelte/scripts/process-messages/templates/server-warnings.js +++ b/packages/svelte/scripts/process-messages/templates/server-warnings.js @@ -4,13 +4,13 @@ var bold = 'font-weight: bold'; var normal = 'font-weight: normal'; /** - * MESSAGE - * @param {string} PARAMETER + * DESCRIPTION + * @param {VALUES} values */ -export function CODE(PARAMETER) { +export function CODE(values) { if (DEV) { console.warn( - `%c[svelte] ${'CODE'}\n%c${MESSAGE}\nhttps://svelte.dev/e/${'CODE'}`, + `%c[svelte] ${'CODE'}\n%c${MESSAGE(values)}\nhttps://svelte.dev/e/${'CODE'}`, bold, normal ); diff --git a/packages/svelte/scripts/process-messages/templates/shared-errors.js b/packages/svelte/scripts/process-messages/templates/shared-errors.js index c72e9f9d5e..de7d8c4e99 100644 --- a/packages/svelte/scripts/process-messages/templates/shared-errors.js +++ b/packages/svelte/scripts/process-messages/templates/shared-errors.js @@ -1,13 +1,13 @@ import { DEV } from 'esm-env'; /** - * MESSAGE - * @param {string} PARAMETER + * DESCRIPTION + * @param {VALUES} values * @returns {never} */ -export function CODE(PARAMETER) { +export function CODE(values) { if (DEV) { - const error = new Error(`${'CODE'}\n${MESSAGE}\nhttps://svelte.dev/e/${'CODE'}`); + const error = new Error(`${'CODE'}\n${MESSAGE(values)}\nhttps://svelte.dev/e/${'CODE'}`); error.name = 'Svelte error'; throw error; } else { diff --git a/packages/svelte/scripts/process-messages/templates/shared-warnings.js b/packages/svelte/scripts/process-messages/templates/shared-warnings.js index 8a9b87b760..7b4a6821fe 100644 --- a/packages/svelte/scripts/process-messages/templates/shared-warnings.js +++ b/packages/svelte/scripts/process-messages/templates/shared-warnings.js @@ -4,13 +4,13 @@ var bold = 'font-weight: bold'; var normal = 'font-weight: normal'; /** - * MESSAGE - * @param {string} PARAMETER + * DESCRIPTION + * @param {VALUES} values */ -export function CODE(PARAMETER) { +export function CODE(values) { if (DEV) { console.warn( - `%c[svelte] ${'CODE'}\n%c${MESSAGE}\nhttps://svelte.dev/e/${'CODE'}`, + `%c[svelte] ${'CODE'}\n%c${MESSAGE(values)}\nhttps://svelte.dev/e/${'CODE'}`, bold, normal ); diff --git a/packages/svelte/src/compiler/errors.js b/packages/svelte/src/compiler/errors.js index ccb7fe833e..c96d214b56 100644 --- a/packages/svelte/src/compiler/errors.js +++ b/packages/svelte/src/compiler/errors.js @@ -3,6 +3,7 @@ import { CompileDiagnostic } from './utils/compile_diagnostic.js'; /** @typedef {{ start?: number, end?: number }} NodeLike */ + class InternalCompileError extends Error { message = ''; // ensure this property is enumerable #diagnostic; @@ -20,7 +21,6 @@ class InternalCompileError extends Error { // But we also want to share the same object shape with that of warnings, therefore // we create an instance of the shared class an copy over its properties. this.#diagnostic = new CompileDiagnostic(code, message, position); - Object.assign(this, this.#diagnostic); this.name = 'CompileError'; } @@ -44,1694 +44,1809 @@ function e(node, code, message) { const start = typeof node === 'number' ? node : node?.start; const end = typeof node === 'number' ? node : node?.end; - throw new InternalCompileError(code, message, start !== undefined ? [start, end ?? start] : undefined); + throw new InternalCompileError( + code, + message, + start !== undefined ? [start, end ?? start] : undefined + ); } /** * Invalid compiler option: %details% * @param {null | number | NodeLike} node - * @param {string} details + * @param {{ "details": string }} values * @returns {never} */ -export function options_invalid_value(node, details) { - e(node, 'options_invalid_value', `Invalid compiler option: ${details}\nhttps://svelte.dev/e/options_invalid_value`); +export function options_invalid_value(node, values) { + e(node, 'options_invalid_value', `${`Invalid compiler option: ${values.details}`}\nhttps://svelte.dev/e/${'options_invalid_value'}`); } /** * Invalid compiler option: %details% * @param {null | number | NodeLike} node - * @param {string} details + * @param {{ "details": string }} values * @returns {never} */ -export function options_removed(node, details) { - e(node, 'options_removed', `Invalid compiler option: ${details}\nhttps://svelte.dev/e/options_removed`); +export function options_removed(node, values) { + e(node, 'options_removed', `${`Invalid compiler option: ${values.details}`}\nhttps://svelte.dev/e/${'options_removed'}`); } /** * Unrecognised compiler option %keypath% * @param {null | number | NodeLike} node - * @param {string} keypath + * @param {{ "keypath": string }} values * @returns {never} */ -export function options_unrecognised(node, keypath) { - e(node, 'options_unrecognised', `Unrecognised compiler option ${keypath}\nhttps://svelte.dev/e/options_unrecognised`); +export function options_unrecognised(node, values) { + e(node, 'options_unrecognised', `${`Unrecognised compiler option ${values.keypath}`}\nhttps://svelte.dev/e/${'options_unrecognised'}`); } /** * `$bindable()` can only be used inside a `$props()` declaration * @param {null | number | NodeLike} node + * @param {void} values * @returns {never} */ -export function bindable_invalid_location(node) { - e(node, 'bindable_invalid_location', `\`$bindable()\` can only be used inside a \`$props()\` declaration\nhttps://svelte.dev/e/bindable_invalid_location`); +export function bindable_invalid_location(node, values) { + e(node, 'bindable_invalid_location', `${`\`$bindable()\` can only be used inside a \`$props()\` declaration`}\nhttps://svelte.dev/e/${'bindable_invalid_location'}`); } /** * Cannot assign to %thing% * @param {null | number | NodeLike} node - * @param {string} thing + * @param {{ "thing": string }} values * @returns {never} */ -export function constant_assignment(node, thing) { - e(node, 'constant_assignment', `Cannot assign to ${thing}\nhttps://svelte.dev/e/constant_assignment`); +export function constant_assignment(node, values) { + e(node, 'constant_assignment', `${`Cannot assign to ${values.thing}`}\nhttps://svelte.dev/e/${'constant_assignment'}`); } /** * Cannot bind to %thing% * @param {null | number | NodeLike} node - * @param {string} thing + * @param {{ "thing": string }} values * @returns {never} */ -export function constant_binding(node, thing) { - e(node, 'constant_binding', `Cannot bind to ${thing}\nhttps://svelte.dev/e/constant_binding`); +export function constant_binding(node, values) { + e(node, 'constant_binding', `${`Cannot bind to ${values.thing}`}\nhttps://svelte.dev/e/${'constant_binding'}`); } /** * `%name%` has already been declared * @param {null | number | NodeLike} node - * @param {string} name + * @param {{ "name": string }} values * @returns {never} */ -export function declaration_duplicate(node, name) { - e(node, 'declaration_duplicate', `\`${name}\` has already been declared\nhttps://svelte.dev/e/declaration_duplicate`); +export function declaration_duplicate(node, values) { + e(node, 'declaration_duplicate', `${`\`${values.name}\` has already been declared`}\nhttps://svelte.dev/e/${'declaration_duplicate'}`); } /** * Cannot declare a variable with the same name as an import from `