fix: parse regexp without parens

parse-regexp-no-paren
gtmnayan 12 months ago
parent 7af165de09
commit 9e6e08eee6

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: parse regexp without parens

@ -40,7 +40,7 @@ export default function mustache(parser) {
parser.index += 1;
parser.allow_whitespace();
// {/if}, {/each}, {/await} or {/key}
if (parser.eat('/')) {
if (parser.match('/')) {
let block = parser.current();
let expected;
if (closing_tag_omitted(block.name)) {
@ -68,8 +68,19 @@ export default function mustache(parser) {
} else if (block.type === 'KeyBlock') {
expected = 'key';
} else {
parser.error(parser_errors.unexpected_block_close);
let possible_regex = read_expression(parser);
parser.allow_whitespace();
parser.eat('}', true);
parser.current().children.push({
start,
end: parser.index,
type: 'MustacheTag',
expression: possible_regex
});
return;
}
parser.index += 1;
parser.eat(expected, true);
parser.allow_whitespace();
parser.eat('}', true);

@ -1,7 +1,8 @@
import * as fs from 'node:fs';
import { assert, describe, it } from 'vitest';
import * as svelte from 'svelte/compiler';
import { try_load_json } from '../helpers.js';
import { try_load_json, try_read_file } from '../helpers.js';
import { walk } from 'estree-walker';
describe('parse', () => {
fs.readdirSync(`${__dirname}/samples`).forEach((dir) => {
@ -26,8 +27,23 @@ describe('parse', () => {
.trimEnd()
.replace(/\r/g, '');
const expectedOutput = try_load_json(`${__dirname}/samples/${dir}/output.json`);
const expectedError = try_load_json(`${__dirname}/samples/${dir}/error.json`);
const output_file = try_read_file(`${__dirname}/samples/${dir}/output.json`);
// Regexp literals are serialized as empty objects, so we need to convert the values back to RegExp
// to make the deepEqual comparison work.
let expectedOutput = output_file
? JSON.parse(output_file, (key, value) => {
if (
typeof value === 'object' &&
value !== null &&
value.type === 'Literal' &&
value.regex
) {
value.value = new RegExp(value.regex.pattern, value.regex.flags);
}
return value;
})
: null;
try {
const { ast } = svelte.compile(
@ -48,6 +64,8 @@ describe('parse', () => {
assert.deepEqual(ast.module, expectedOutput.module);
} catch (err) {
if (err.name !== 'ParseError') throw err;
const expectedError = try_load_json(`${__dirname}/samples/${dir}/error.json`);
if (!expectedError) throw err;
const { code, message, pos, start } = err;

@ -0,0 +1,102 @@
{
"html": {
"start": 0,
"end": 19,
"type": "Fragment",
"children": [
{
"start": 0,
"end": 19,
"type": "MustacheTag",
"expression": {
"type": "CallExpression",
"start": 1,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 1
},
"end": {
"line": 1,
"column": 18
}
},
"callee": {
"type": "MemberExpression",
"start": 1,
"end": 11,
"loc": {
"start": {
"line": 1,
"column": 1
},
"end": {
"line": 1,
"column": 11
}
},
"object": {
"type": "Literal",
"start": 1,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 1
},
"end": {
"line": 1,
"column": 6
}
},
"raw": "/abc/",
"regex": {
"pattern": "abc",
"flags": ""
}
},
"property": {
"type": "Identifier",
"start": 7,
"end": 11,
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 11
}
},
"name": "test"
},
"computed": false,
"optional": false
},
"arguments": [
{
"type": "Literal",
"start": 12,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 12
},
"end": {
"line": 1,
"column": 17
}
},
"value": "abc",
"raw": "\"abc\""
}
],
"optional": false
}
}
]
}
}
Loading…
Cancel
Save