-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.ts
85 lines (72 loc) · 1.99 KB
/
index.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
76
77
78
79
80
81
82
83
84
85
import { NodePath } from "@babel/traverse";
import {
CallExpression,
Comment,
CommentBlock,
Identifier,
} from "@babel/types";
const PURE_ANNOTATION = "#__PURE__";
const isPureAnnotated = (comments: ReadonlyArray<Comment> | null): boolean => {
if (typeof comments === "undefined") {
return false;
}
if (comments && comments.length > 0) {
return comments[comments.length - 1].value === PURE_ANNOTATION;
}
return false;
};
const createComponentBlock = (value: string): Comment =>
({
type: "CommentBlock",
value,
} as CommentBlock);
const isVariableUsedInCallback = (nodePath: NodePath<any>) => {
let used = false;
const scope = nodePath.parentPath.scope;
nodePath.traverse({
ReferencedIdentifier(n: NodePath<Identifier>) {
if (scope.hasOwnBinding(n.node.name)) {
used = true;
}
},
} as any);
return used;
};
const isPureCall = (nodePath: NodePath<CallExpression>) => {
if (nodePath.parentPath.isAssignmentExpression()) {
return nodePath;
}
if (nodePath.parentPath.isVariableDeclarator()) {
return !isVariableUsedInCallback(nodePath);
}
if (
nodePath.parentPath.isCallExpression() &&
(
(nodePath.parentPath.get("arguments") as any) || ([] as NodePath[])
).indexOf(nodePath) > -1
) {
return true;
}
return false;
};
export default () => ({
name: "pure-calls-annotation",
inherits: require("@babel/plugin-syntax-dynamic-import").default,
visitor: {
CallExpression: {
enter(nodePath: NodePath<CallExpression>) {
if (isPureCall(nodePath)) {
if (!isPureAnnotated(nodePath.node.leadingComments)) {
const pureAnnotation = createComponentBlock(PURE_ANNOTATION);
nodePath.replaceWith({
...nodePath.node,
leadingComments: nodePath.node.leadingComments
? nodePath.node.leadingComments.concat(pureAnnotation)
: [pureAnnotation],
} as any);
}
}
},
},
},
});