Skip to content

Commit 887b7eb

Browse files
Merge pull request #356 from ckwalsh/pr356
[Perf] Improve performance of removeNodesFromOriginalCode()
2 parents 92e5374 + 9266fdb commit 887b7eb

File tree

1 file changed

+29
-35
lines changed

1 file changed

+29
-35
lines changed
Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
1-
import {
2-
CommentBlock,
3-
CommentLine,
4-
Directive,
5-
ImportDeclaration,
6-
InterpreterDirective,
7-
Statement,
8-
} from '@babel/types';
1+
import { Comment, Node } from '@babel/types';
92

10-
/** Escapes a string literal to be passed to new RegExp. See: https://stackoverflow.com/a/6969486/480608.
11-
* @param s the string to escape
12-
*/
13-
const escapeRegExp = (s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
3+
type NodeOrComment = Node | Comment;
4+
type BoundedNodeOrComment = NodeOrComment & { start: number; end: number };
145

156
/**
167
* Removes imports from original file
@@ -19,30 +10,33 @@ const escapeRegExp = (s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1910
*/
2011
export const removeNodesFromOriginalCode = (
2112
code: string,
22-
nodes: (
23-
| Statement
24-
| CommentBlock
25-
| Directive
26-
| CommentLine
27-
| ImportDeclaration
28-
| InterpreterDirective
29-
)[],
13+
nodes: (Node | Comment)[],
3014
) => {
31-
let text = code;
32-
for (const node of nodes) {
33-
const start = Number(node.start);
34-
const end = Number(node.end);
35-
if (Number.isSafeInteger(start) && Number.isSafeInteger(end)) {
36-
text = text.replace(
37-
// only replace imports at the beginning of the line (ignoring whitespace)
38-
// otherwise matching commented imports will be replaced
39-
new RegExp(
40-
'^\\s*' + escapeRegExp(code.substring(start, end)),
41-
'm',
42-
),
43-
'',
44-
);
15+
const ranges: { start: number; end: number }[] = nodes.filter(
16+
(node): node is BoundedNodeOrComment => {
17+
const start = Number(node.start);
18+
const end = Number(node.end);
19+
return Number.isSafeInteger(start) && Number.isSafeInteger(end);
20+
},
21+
);
22+
ranges.sort((a, b) => a.start - b.start);
23+
24+
let result: string = '';
25+
let idx = 0;
26+
27+
for (const { start, end } of ranges) {
28+
if (start > idx) {
29+
result += code.slice(idx, start);
30+
idx = start;
31+
}
32+
if (end > idx) {
33+
idx = end;
4534
}
4635
}
47-
return text;
36+
37+
if (idx < code.length) {
38+
result += code.slice(idx);
39+
}
40+
41+
return result;
4842
};

0 commit comments

Comments
 (0)