This repository was archived by the owner on Oct 9, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathconvert-statement-to-segment-callable.ts
75 lines (68 loc) · 2.11 KB
/
convert-statement-to-segment-callable.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import * as t from "@babel/types";
import { DEFAULT_SEGMENT_CALLABLE_VARIABLE_NAME } from "~/utils/constants";
export function convertStatementToSegmentCallable(
statement: babel.NodePath<babel.types.Statement>,
{
initialValue,
cacheNullValue,
segmentCallableId = statement.scope.generateUidIdentifier(
DEFAULT_SEGMENT_CALLABLE_VARIABLE_NAME
),
}: {
initialValue?: t.Expression;
performReplacement?: boolean;
cacheNullValue?: t.Expression;
segmentCallableId?: t.Identifier;
}
) {
const parentDeclaration = statement.find((p) =>
p.isVariableDeclaration()
) as babel.NodePath<babel.types.VariableDeclaration> | null;
const makeSegmentCallable = (statements: t.Statement[]) => {
return t.variableDeclaration("const", [
t.variableDeclarator(
segmentCallableId,
t.arrowFunctionExpression(
[],
t.blockStatement(
statements.concat(
cacheNullValue ? [t.returnStatement(cacheNullValue)] : []
)
)
)
),
]);
};
let replacements: t.Node[] | null = null;
if (parentDeclaration) {
const newKind = parentDeclaration.node.kind === "var" ? "var" : "let";
const newDeclaration = t.variableDeclaration(
newKind,
parentDeclaration.node.declarations.map((declaration) => {
return t.variableDeclarator(declaration.id, initialValue);
})
);
const assignmentExpressionStatements = parentDeclaration.node.declarations
.map((declarator) => {
return declarator.init
? t.expressionStatement(
t.assignmentExpression("=", declarator.id, declarator.init)
)
: null;
})
.filter((v): v is t.ExpressionStatement => Boolean(v));
replacements = [
newDeclaration,
makeSegmentCallable(assignmentExpressionStatements),
];
} else {
replacements = [makeSegmentCallable([statement.node])];
}
const prformTransformation = () =>
replacements ? statement.replaceWithMultiple(replacements) : null;
return {
segmentCallableId,
replacements,
prformTransformation,
};
}