From 4fef1d3afb23c041660a2ba3675d651316e7807f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20Deng=20=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90?= Date: Sat, 4 May 2024 06:06:51 +0900 Subject: [PATCH] fix: escape string and template literal (#8) --- src/commands/to-string-literal.test.ts | 19 ++++++++++++--- src/commands/to-string-literal.ts | 10 ++++---- src/commands/to-template-literal.test.ts | 31 ++++++++++++++++++++++++ src/commands/to-template-literal.ts | 9 +++++-- 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/commands/to-string-literal.test.ts b/src/commands/to-string-literal.test.ts index a22543d..ffe243b 100644 --- a/src/commands/to-string-literal.test.ts +++ b/src/commands/to-string-literal.test.ts @@ -9,7 +9,7 @@ run( const a = \`a\`; const b = \`b\`; const c = 'c'; `, output: d` - const a = 'a'; const b = 'b'; const c = 'c'; + const a = "a"; const b = "b"; const c = 'c'; `, errors: ['command-removal', 'command-fix', 'command-fix'], }, @@ -20,7 +20,7 @@ run( const a = \`a\`, b = \`b\`, c = \`c\`, d = \`d\`; `, output: d` - const a = \`a\`, b = 'b', c = 'c', d = \`d\`; + const a = \`a\`, b = "b", c = "c", d = \`d\`; `, errors: ['command-removal', 'command-fix', 'command-fix'], }, @@ -31,7 +31,7 @@ run( const a = 'a', b = 'b', c = \`c\`, d = 'd', e = \`e\`, f = \`f\`; `, output: d` - const a = 'a', b = 'b', c = 'c', d = 'd', e = \`e\`, f = 'f'; + const a = 'a', b = 'b', c = "c", d = 'd', e = \`e\`, f = "f"; `, errors: ['command-removal', 'command-fix', 'command-fix'], }, @@ -42,7 +42,18 @@ run( const a = \`\${g}a\${a}a\${b}c\${d}e\${a}\`; `, output: d` - const a = g + 'a' + a + 'a' + b + 'c' + d + 'e' + a; + const a = g + "a" + a + "a" + b + "c" + d + "e" + a; + `, + errors: ['command-removal', 'command-fix'], + }, + // escape + { + code: d` + // @2sl + const a = \`"\\"\\\\"\` + `, + output: d` + const a = "\\"\\\\\\"\\\\\\\\\\"" `, errors: ['command-removal', 'command-fix'], }, diff --git a/src/commands/to-string-literal.ts b/src/commands/to-string-literal.ts index 7c721d0..50d4c70 100644 --- a/src/commands/to-string-literal.ts +++ b/src/commands/to-string-literal.ts @@ -19,12 +19,12 @@ export const toStringLiteral: Command = { ctx.removeComment() for (const node of getNodesByIndexes(nodes, indexes)) { const ids = extractIdentifiers(node) - let raw = ctx.source.getText(node).slice(1, -1) + let raw = JSON.stringify(ctx.source.getText(node).slice(1, -1)).slice(1, -1) if (ids.length) raw = toStringWithIds(raw, node, ids) else - raw = `'${raw}'` + raw = `"${raw}"` ctx.report({ node, @@ -56,8 +56,8 @@ function toStringWithIds(raw: string, node: Tree.TemplateLiteral, ids: Identifie let hasStart = false let hasEnd = false ids.forEach(({ name, range }, index) => { - let startStr = `' + ` - let endStr = ` + '` + let startStr = `" + ` + let endStr = ` + "` if (index === 0) { hasStart = range[0] - /* `${ */3 === node.range[0] @@ -72,5 +72,5 @@ function toStringWithIds(raw: string, node: Tree.TemplateLiteral, ids: Identifie raw = raw.replace(`\${${name}}`, `${startStr}${name}${endStr}`) }) - return `${hasStart ? '' : `'`}${raw}${hasEnd ? '' : `'`}` + return `${hasStart ? '' : `"`}${raw}${hasEnd ? '' : `"`}` } diff --git a/src/commands/to-template-literal.test.ts b/src/commands/to-template-literal.test.ts index 398e2dd..426bfd7 100644 --- a/src/commands/to-template-literal.test.ts +++ b/src/commands/to-template-literal.test.ts @@ -86,4 +86,35 @@ run( `, errors: ['command-removal', 'command-fix', 'command-fix'], }, + // escape + { + code: d` + // @2tl + const a = "\`" + `, + output: d` + const a = \`\\\`\` + `, + errors: ['command-removal', 'command-fix'], + }, + { + code: d` + // @2tl + const a = str + "\`" + `, + output: d` + const a = \`\${str}\\\`\` + `, + errors: ['command-removal', 'command-fix'], + }, + { + code: d` + // @2tl + const a = "\${str}" + `, + output: d` + const a = \`\\\${str}\` + `, + errors: ['command-removal', 'command-fix'], + }, ) diff --git a/src/commands/to-template-literal.ts b/src/commands/to-template-literal.ts index e214f1f..677292c 100644 --- a/src/commands/to-template-literal.ts +++ b/src/commands/to-template-literal.ts @@ -51,7 +51,7 @@ function getExpressionValue(node: Tree.Expression | Tree.PrivateIdentifier) { if (node.type === 'Identifier') return `\${${node.name}}` if (node.type === 'Literal' && typeof node.value === 'string') - return node.value + return escape(node.value) return '' } @@ -76,7 +76,7 @@ function traverseBinaryExpression(node: Tree.BinaryExpression): string { } function convertStringLiteral(node: Tree.StringLiteral, ctx: CommandContext) { - const raw = `\`${node.value}\`` + const raw = `\`${escape(node.value)}\`` report(ctx, node, raw) } @@ -89,3 +89,8 @@ function report(ctx: CommandContext, node: Tree.Node, raw: string) { }, }) } + +function escape(raw: string) { + // TODO handle multi escape characters '\\${str}' + return raw.replace(/`/g, '\\`').replace(/\$\{/g, '\\${') +}