forked from babel/babel
/
index.js
61 lines (58 loc) 路 1.63 KB
/
index.js
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
import { declare } from "@babel/helper-plugin-utils";
import syntaxClassStaticBlock from "@babel/plugin-syntax-class-static-block";
/**
* Generate a uid that is not in `denyList`
*
* @param {*} scope
* @param {Set<string>} a deny list that the generated uid should avoid
* @returns
*/
function generateUid(scope, denyList: Set<string>) {
const name = "";
let uid;
let i = 1;
do {
uid = scope._generateUid(name, i);
i++;
} while (denyList.has(uid));
return uid;
}
export default declare(({ types: t, template, assertVersion }) => {
// todo: change to ^7.12.0 when it is published
assertVersion("^7.11.6");
return {
name: "proposal-class-static-block",
inherits: syntaxClassStaticBlock,
visitor: {
Class(path: NodePath<Class>) {
const { scope } = path;
const classBody = path.get("body");
const privateNames = new Set();
let staticBlockPath;
for (const path of classBody.get("body")) {
if (path.isPrivate()) {
privateNames.add(path.get("key.id").node.name);
} else if (path.isStaticBlock()) {
staticBlockPath = path;
}
}
if (!staticBlockPath) {
return;
}
const staticBlockRef = t.privateName(
t.identifier(generateUid(scope, privateNames)),
);
classBody.pushContainer(
"body",
t.classPrivateProperty(
staticBlockRef,
template.expression.ast`(() => { ${staticBlockPath.node.body} })()`,
[],
/* static */ true,
),
);
staticBlockPath.remove();
},
},
};
});