Skip to content

Commit 5911765

Browse files
committed
feat: new code action to convert first of string method replace to regex eg:
`''.replace('a(', '...') -> ''.replace(/a\(/, '...')`. Note that there is `matchAll` method for match all behavior and this refactoring intended for matching customization.
1 parent 1148454 commit 5911765

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { CodeAction } from './getCodeActions'
2+
import escapeStringRegexp from 'escape-string-regexp'
3+
4+
const nodeToSpan = (node: ts.Node): ts.TextSpan => {
5+
const start = node.pos + (node.getLeadingTriviaWidth() ?? 0)
6+
return { start, length: node.end - start }
7+
}
8+
9+
export default {
10+
id: 'changeStringReplaceToRegex',
11+
name: 'Change to Regex',
12+
tryToApply(sourceFile, position, _range, node) {
13+
if (!node || !position) return
14+
// requires full explicit object selection (be aware of comma) to not be annoying with suggestion
15+
if (!ts.isStringLiteral(node)) return
16+
if (!ts.isCallExpression(node.parent) || node.parent.arguments[0] !== node) return
17+
if (!ts.isPropertyAccessExpression(node.parent.expression)) return
18+
if (node.parent.expression.name.text !== 'replace') return
19+
// though it does to much escaping and ideally should be simplified
20+
const edits: ts.TextChange[] = [{ span: nodeToSpan(node), newText: `/${escapeStringRegexp(node.text)}/` }]
21+
return {
22+
edits: [
23+
{
24+
fileName: sourceFile.fileName,
25+
textChanges: edits,
26+
},
27+
],
28+
}
29+
},
30+
} satisfies CodeAction

typescript/src/codeActions/getCodeActions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { compact } from '@zardoy/utils'
22
import { findChildContainingPosition } from '../utils'
33
import objectSwapKeysAndValues from './objectSwapKeysAndValues'
4+
import changeStringReplaceToRegex from './changeStringReplaceToRegex'
45
import toggleBraces from './toggleBraces'
56

67
type SimplifiedRefactorInfo =
@@ -24,7 +25,7 @@ export type CodeAction = {
2425
tryToApply: ApplyCodeAction
2526
}
2627

27-
const codeActions: CodeAction[] = [/* toggleBraces */ objectSwapKeysAndValues]
28+
const codeActions: CodeAction[] = [/* toggleBraces */ objectSwapKeysAndValues, changeStringReplaceToRegex]
2829

2930
export const REFACTORS_CATEGORY = 'essential-refactors'
3031

0 commit comments

Comments
 (0)