diff --git a/packages/svelte/src/compiler/phases/1-parse/acorn.js b/packages/svelte/src/compiler/phases/1-parse/acorn.js index 755086678c..c9c9d184ac 100644 --- a/packages/svelte/src/compiler/phases/1-parse/acorn.js +++ b/packages/svelte/src/compiler/phases/1-parse/acorn.js @@ -61,7 +61,7 @@ export function parse(source, comments, typescript, is_script) { } catch (err) { // TODO the `return` in necessary for TS<7 due to a bug; otherwise // the `finally` block is regarded as unreachable - return handle_parse_error(err, source, typescript); + return handle_parse_error(err); } finally { if (is_script) { // @ts-expect-error @@ -102,15 +102,15 @@ const regex_position_indicator = / \(\d+:\d+\)$/; /** * @param {any} err - * @param {string} source - * @param {boolean} typescript + * @param {string} [source] + * @param {boolean} [typescript] * @returns {never} */ function handle_parse_error(err, source, typescript) { let message = /** @type {string} */ (err.message).replace(regex_position_indicator, ''); let pos = /** @type {number} */ (err.pos); - if (typescript && source[pos] === ':') { + if (!typescript && source && source[pos] === ':') { message += ` (did you forget to add \`lang="ts"\`?)`; } diff --git a/packages/svelte/src/compiler/phases/1-parse/read/expression.js b/packages/svelte/src/compiler/phases/1-parse/read/expression.js index 6beff287c5..736639e1f4 100644 --- a/packages/svelte/src/compiler/phases/1-parse/read/expression.js +++ b/packages/svelte/src/compiler/phases/1-parse/read/expression.js @@ -33,11 +33,8 @@ export function get_loose_identifier(parser, opening_token) { * @returns {Expression} */ export default function read_expression(parser, opening_token, disallow_loose) { - /** @type {ReturnType} */ - let node; - try { - node = parse_expression_at(parser, parser.template, parser.index); + const node = parse_expression_at(parser, parser.template, parser.index); let index = /** @type {number} */ (node.end); @@ -45,6 +42,24 @@ export default function read_expression(parser, opening_token, disallow_loose) { if (last_comment && last_comment.end > index) index = last_comment.end; parser.index = index; + + if (!parser.ts) { + let j = parser.index; + while (j < parser.template.length && regex_whitespace.test(parser.template[j])) j++; + + const remaining = parser.template.slice(j); + + if ( + remaining[0] === ':' || + /^satisfies[\s(]/.test(remaining) || + (remaining[0] === '!' && remaining[1] !== '=') || + (/^as[\s(]/.test(remaining) && !disallow_loose) + ) { + e.js_parse_error(j, `Unexpected token (did you forget to add \`lang="ts"\`?)`); + } + } + + return /** @type {Expression} */ (remove_parens(node)); } catch (err) { // If we are in an each loop we need the error to be thrown in cases like // `as { y = z }` so we still throw and handle the error there @@ -57,22 +72,4 @@ export default function read_expression(parser, opening_token, disallow_loose) { throw err; } - - if (!parser.ts) { - let j = parser.index; - while (j < parser.template.length && regex_whitespace.test(parser.template[j])) j++; - - const remaining = parser.template.slice(j); - - if ( - remaining[0] === ':' || - /^satisfies[\s(]/.test(remaining) || - (remaining[0] === '!' && remaining[1] !== '=') || - (/^as[\s(]/.test(remaining) && !disallow_loose) - ) { - e.js_parse_error(j, `Unexpected token (did you forget to add \`lang="ts"\`?)`); - } - } - - return /** @type {Expression} */ (remove_parens(node)); } diff --git a/packages/svelte/src/compiler/phases/1-parse/state/tag.js b/packages/svelte/src/compiler/phases/1-parse/state/tag.js index 568761806d..ff153128a5 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/tag.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/tag.js @@ -390,19 +390,11 @@ function open(parser) { const prelude = parser.template.slice(0, params_start).replace(/\S/g, ' '); const params = parser.template.slice(params_start, parser.index); - let function_expression; - - if (matched) { - try { - function_expression = /** @type {ArrowFunctionExpression} */ ( + let function_expression = matched + ? /** @type {ArrowFunctionExpression} */ ( parse_expression_at(parser, prelude + `${params} => {}`, params_start) - ); - } catch (/** @type {any} */ err) { - parser.acorn_error(err); - } - } else { - function_expression = { params: [] }; - } + ) + : { params: [] }; parser.allow_whitespace(); parser.eat('}', true);