Skip to content

Commit

Permalink
Merge branch 'main' into sourcemap-mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich-Harris committed Jan 9, 2025
2 parents 42daa43 + e1caca6 commit 029d0cb
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# esrap changelog

## 1.4.1

### Patch Changes

- 10c6156: fix: escape newlines when quoting strings

## 1.4.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "esrap",
"version": "1.4.0",
"version": "1.4.1",
"description": "Parse in reverse",
"repository": {
"type": "git",
Expand Down
21 changes: 20 additions & 1 deletion src/handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,26 @@ function prepend_comments(comments, state, newlines) {
* @param {'\'' | '"'} char
*/
function quote(string, char) {
return char + string.replaceAll(char, '\\' + char) + char;
let out = char;
let escaped = false;

for (const c of string) {
if (escaped) {
out += c;
escaped = false;
} else if (c === '\\') {
out += '\\\\';
escaped = true;
} else if (c === char) {
out += '\\' + c;
} else if (c === '\n') {
out += '\\n';
} else {
out += c;
}
}

return out + char;
}

const OPERATOR_PRECEDENCE = {
Expand Down
32 changes: 32 additions & 0 deletions test/quotes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,35 @@ test('escape double quotes if present in string literal', () => {

expect(code).toMatchInlineSnapshot(`"const foo = "b\\"ar";"`);
});

test('escapes new lines', () => {
const ast = load('const str = "a\\nb"');
clean(ast);
const code = print(ast).code;

expect(code).toMatchInlineSnapshot(`"const str = 'a\\nb';"`);
});

test('escapes escape characters', () => {
const ast = load('const str = "a\\\\nb"');
clean(ast);
const code = print(ast).code;

expect(code).toMatchInlineSnapshot(`"const str = 'a\\\\nb';"`);
});

test('does not escape already-escaped single quotes', () => {
const ast = load(`const str = 'a\\'b'`);
clean(ast);
const code = print(ast).code;

expect(code).toMatchInlineSnapshot(`"const str = 'a\\'b';"`);
});

test('does not escape already-escaped double quotes', () => {
const ast = load('const str = "a\\"b"');
clean(ast);
const code = print(ast).code;

expect(code).toMatchInlineSnapshot(`"const str = 'a"b';"`);
});

0 comments on commit 029d0cb

Please sign in to comment.