diff --git a/src/compiler/parse/acorn.ts b/src/compiler/parse/acorn.ts index b88454151..c70756d79 100644 --- a/src/compiler/parse/acorn.ts +++ b/src/compiler/parse/acorn.ts @@ -14,32 +14,25 @@ export const parse = (source: string): Node => { // }); }; -export const parse_expression_at = (source: string, index: number) => { +export const parse_expression_at = (source: string, index: number): number => { // TODO: Clean up after acorn -> @babel/parser move try { + // First, try to parse the expression. Unlike acorn, @babel/parser isn't relaxed + // enough to just stop after the first expression, so we almost always expect a + // parser error here instead. This is expected, so handle it. parseExpression(source.slice(index), { sourceType: 'module', plugins: ['jsx', 'typescript'], }); throw new Error('Parse error.'); // Expected to fail. } catch (err) { - if (!err.pos) { - throw err; + if (err.message.startsWith('Unexpected token') && source[index + err.pos] === '}') { + return index + err.pos; } - try { - const result = parseExpression(source.slice(index, index + err.pos), { - sourceType: 'module', - plugins: ['jsx', 'typescript'], - }); - result.start = index; - result.end = index + err.pos; - return result; - } catch (err2) { - if (err2.pos) { - err2.pos = index + err2.pos; - } - throw err2; + if (err.pos) { + err.pos = index + err.pos; } + throw err; } }; // acornJsx.parseExpressionAt(source, index, { diff --git a/src/compiler/parse/read/expression.ts b/src/compiler/parse/read/expression.ts index 827a29721..1fe5f05f1 100644 --- a/src/compiler/parse/read/expression.ts +++ b/src/compiler/parse/read/expression.ts @@ -1,20 +1,19 @@ -// @ts-nocheck - import { parse_expression_at } from '../acorn.js'; import { Parser } from '../index.js'; import { whitespace } from '../../utils/patterns.js'; // import { Node } from 'estree'; +// @ts-ignore export default function read_expression(parser: Parser): string { try { - const node = parse_expression_at(parser.template, parser.index); + const start = parser.index; + let index = parse_expression_at(parser.template, parser.index); let num_parens = 0; - for (let i = parser.index; i < node.start; i += 1) { + for (let i = parser.index; i < start; i += 1) { if (parser.template[i] === '(') num_parens += 1; } - let index = node.end; while (num_parens > 0) { const char = parser.template[index]; @@ -35,7 +34,7 @@ export default function read_expression(parser: Parser): string { parser.index = index; - return parser.template.substring(node.start, node.end); + return parser.template.substring(start, index); // return node as Node; } catch (err) { parser.acorn_error(err);