Skip to content

Commit

Permalink
improve
Browse files Browse the repository at this point in the history
  • Loading branch information
liuxingbaoyu committed Mar 4, 2023
1 parent 9a85d70 commit 93b8a00
Show file tree
Hide file tree
Showing 20 changed files with 116 additions and 96 deletions.
100 changes: 71 additions & 29 deletions packages/babel-plugin-transform-typescript/src/enum.ts
Expand Up @@ -6,6 +6,21 @@ type t = typeof t;

const ENUMS = new WeakMap<t.Identifier, PreviousEnumMembers>();

const buildEnumWrapper = template.statement(`
(function (ID) {
ASSIGNMENTS;
})(ID || (ID = {}));
`);

const buildPureEnumWrapper = template.expression(
`
/*#__PURE__*/(function (ID) {
ASSIGNMENTS;
})(ID || {})
`,
{ preserveComments: true },
);

export default function transpileEnum(
path: NodePath<t.TSEnumDeclaration>,
t: t,
Expand All @@ -18,24 +33,50 @@ export default function transpileEnum(
}

const name = node.id.name;
const { wrapper: fill, data } = enumFill(path, t, node.id);
const { fill, data, isPure } = enumFill(path, t, node.id);

switch (path.parent.type) {
case "BlockStatement":
case "ExportNamedDeclaration":
case "Program": {
path.insertAfter(fill);
if (seen(path.parentPath)) {
path.remove();
// todo: Consider exclude program with import/export
// && !path.parent.body.some(n => t.isImportDeclaration(n) || t.isExportDeclaration(n));
const isGlobal = t.isProgram(path.parent);

if (isPure && isGlobal) {
if (seen(path.parentPath)) {
path.replaceWith(
t.assignmentExpression(
"=",
t.cloneNode(node.id),
buildPureEnumWrapper(fill),
),
);
} else {
path.scope.registerDeclaration(
path.replaceWith(
t.variableDeclaration("var", [
t.variableDeclarator(node.id, buildPureEnumWrapper(fill)),
]),
)[0],
);
}
} else {
// todo: Consider exclude program with import/export
// && !path.parent.body.some(n => t.isImportDeclaration(n) || t.isExportDeclaration(n));
const isGlobal = t.isProgram(path.parent);
path.scope.registerDeclaration(
path.replaceWith(makeVar(node.id, t, isGlobal ? "var" : "let"))[0],
);
ENUMS.set(path.scope.getBindingIdentifier(name), data);
path.insertAfter(buildEnumWrapper(fill));

if (seen(path.parentPath)) {
path.remove();
} else {
path.scope.registerDeclaration(
path.replaceWith(
t.variableDeclaration(isGlobal ? "var" : "let", [
t.variableDeclarator(node.id),
]),
)[0],
);
}
}
ENUMS.set(path.scope.getBindingIdentifier(name), data);
break;
}

Expand All @@ -57,16 +98,6 @@ export default function transpileEnum(
}
}

function makeVar(id: t.Identifier, t: t, kind: "var" | "let" | "const") {
return t.variableDeclaration(kind, [t.variableDeclarator(id)]);
}

const buildEnumWrapper = template(`
(function (ID) {
ASSIGNMENTS;
})(ID || (ID = {}));
`);

const buildStringAssignment = template(`
ENUM["NAME"] = VALUE;
`);
Expand All @@ -83,7 +114,7 @@ const buildEnumMember = (isString: boolean, options: Record<string, unknown>) =>
* `(function (E) { ... assignments ... })(E || (E = {}));`
*/
function enumFill(path: NodePath<t.TSEnumDeclaration>, t: t, id: t.Identifier) {
const { enumValues: x, data } = translateEnumValues(path, t);
const { enumValues: x, data, isPure } = translateEnumValues(path, t);
const assignments = x.map(([memberName, memberValue]) =>
buildEnumMember(t.isStringLiteral(memberValue), {
ENUM: t.cloneNode(id),
Expand All @@ -93,11 +124,12 @@ function enumFill(path: NodePath<t.TSEnumDeclaration>, t: t, id: t.Identifier) {
);

return {
wrapper: buildEnumWrapper({
fill: {
ID: t.cloneNode(id),
ASSIGNMENTS: assignments,
}),
data: data,
},
data,
isPure,
};
}

Expand Down Expand Up @@ -141,10 +173,11 @@ export function translateEnumValues(path: NodePath<t.TSEnumDeclaration>, t: t) {
// Start at -1 so the first enum member is its increment, 0.
let constValue: number | string | undefined = -1;
let lastName: string;
let isPure = true;

return {
data: seen,
enumValues: path.get("members").map(memberPath => {
const enumValues: Array<[name: string, value: t.Expression]> = path
.get("members")
.map(memberPath => {
const member = memberPath.node;
const name = t.isIdentifier(member.id) ? member.id.name : member.id.value;
const initializerPath = memberPath.get("initializer");
Expand All @@ -161,6 +194,10 @@ export function translateEnumValues(path: NodePath<t.TSEnumDeclaration>, t: t) {
value = t.stringLiteral(constValue);
}
} else {
if (isPure && !initializerPath.isPure()) {
isPure = false;
}

if (initializerPath.isReferencedIdentifier()) {
ReferencedIdentifier(initializerPath, {
t,
Expand Down Expand Up @@ -197,7 +234,12 @@ export function translateEnumValues(path: NodePath<t.TSEnumDeclaration>, t: t) {

lastName = name;
return [name, value];
}) as Array<[name: string, value: t.Expression]>,
});

return {
isPure,
data: seen,
enumValues,
};
}

Expand Down
@@ -1,5 +1,4 @@
// Not type-correct code
var E;
(function (E) {
var E = /*#__PURE__*/function (E) {
E[E["A"] = true] = "A";
})(E || (E = {}));
}(E || {});
@@ -1,3 +1,2 @@
// With --isolatedModules, TSC ignores the "const" modifier when compiling enums
var E;
(function (E) {})(E || (E = {}));
var E = /*#__PURE__*/function (E) {}(E || {});
@@ -1,5 +1,4 @@
var E;
(function (E) {
var E = /*#__PURE__*/function (E) {
E[E["a"] = 0] = "a";
E[E["b"] = 3] = "b";
E[E["c"] = 1] = "c";
Expand All @@ -18,4 +17,4 @@ var E;
E[E["p"] = -3] = "p";
E[E["q"] = 5.4] = "q";
E[E["r"] = 6.4] = "r";
})(E || (E = {}));
}(E || {});
@@ -1,5 +1,4 @@
var E;
(function (E) {
var E = /*#__PURE__*/function (E) {
E[E["x"] = 0] = "x";
E[E["y"] = 1] = "y";
})(E || (E = {}));
}(E || {});
@@ -1,5 +1,4 @@
var E;
(function (E) {
var E = /*#__PURE__*/function (E) {
E[E["a"] = 10] = "a";
E[E["b"] = 10] = "b";
})(E || (E = {}));
}(E || {});
@@ -1,10 +1,9 @@
var x = 10;
var Foo;
(function (Foo) {
var Foo = /*#__PURE__*/function (Foo) {
Foo[Foo["a"] = 10] = "a";
Foo[Foo["b"] = 10] = "b";
Foo[Foo["c"] = 20] = "c";
})(Foo || (Foo = {}));
}(Foo || {});
var Bar;
(function (Bar) {
Bar[Bar["D"] = 10] = "D";
Expand Down
@@ -1,8 +1,7 @@
var E;
(function (E) {
var E = /*#__PURE__*/function (E) {
E[E["x"] = 1] = "x";
E[E["y"] = 2] = "y";
})(E || (E = {}));
(function (E) {
}(E || {});
E = /*#__PURE__*/function (E) {
E[E["z"] = 3] = "z";
})(E || (E = {}));
}(E || {});
@@ -1,14 +1,12 @@
var socketType;
(function (socketType) {
var socketType = /*#__PURE__*/function (socketType) {
socketType[socketType["SOCKET"] = 0] = "SOCKET";
socketType[socketType["SERVER"] = 1] = "SERVER";
socketType[socketType["IPC"] = 2] = "IPC";
})(socketType || (socketType = {}));
var constants;
(function (constants) {
}(socketType || {});
var constants = /*#__PURE__*/function (constants) {
constants[constants["SOCKET"] = 0] = "SOCKET";
constants[constants["SERVER"] = 1] = "SERVER";
constants[constants["IPC"] = 2] = "IPC";
constants[constants["UV_READABLE"] = 3] = "UV_READABLE";
constants[constants["UV_WRITABLE"] = 4] = "UV_WRITABLE";
})(constants || (constants = {}));
}(constants || {});
@@ -1,4 +1,3 @@
var E;
(function (E) {
var E = /*#__PURE__*/function (E) {
E["A"] = "Hey";
})(E || (E = {}));
}(E || {});
@@ -1,7 +1,6 @@
var E;
(function (E) {
var E = /*#__PURE__*/function (E) {
E[E["A"] = 0] = "A";
E["B"] = "";
E[E["A2"] = 0] = "A2";
E["B2"] = "";
})(E || (E = {}));
}(E || {});
@@ -1,4 +1,3 @@
var E;
(function (E) {
var E = /*#__PURE__*/function (E) {
E["A"] = "HALLOWERLD";
})(E || (E = {}));
}(E || {});
Expand Up @@ -2,18 +2,16 @@

const BaseValue = 10;
const Prefix = "/data";
var Values; // 12
(function (Values) {
var Values = /*#__PURE__*/function (Values) {
Values[Values["First"] = 10] = "First";
Values[Values["Second"] = 11] = "Second";
Values[Values["Third"] = 12] = "Third";
})(Values || (Values = {}));
}(Values || {}); // 12
const xxx = 100 + Values.First;
const yyy = xxx;
var Routes;
(function (Routes) {
var Routes = /*#__PURE__*/function (Routes) {
Routes["Parts"] = "/data/parts";
Routes["Invoices"] = "/data/invoices";
Routes["x"] = "10/x";
Routes["y"] = "110/y";
})(Routes || (Routes = {}));
}(Routes || {});
@@ -1,19 +1,17 @@
export class C2 {}
// everything removed
export { C2 as C3 }; // only C2->C3
var BB;
(function (BB) {
var BB = /*#__PURE__*/function (BB) {
BB[BB["K"] = 0] = "K";
})(BB || (BB = {}));
(function (BB) {
}(BB || {});
BB = /*#__PURE__*/function (BB) {
BB["L"] = "LL";
})(BB || (BB = {}));
}(BB || {});
export { BB }; // only BB

// everything removed
export { BB as BB1 }; // BB->BB1
var BB2;
(function (BB2) {})(BB2 || (BB2 = {}));
var BB2 = /*#__PURE__*/function (BB2) {}(BB2 || {});
function foo() {}
export { BB2 as BB3, foo }; // only BB2->BB3 and foo

Expand Down
@@ -1,4 +1,3 @@
var None;
(function (None) {})(None || (None = {}));
var None = /*#__PURE__*/function (None) {}(None || {});
;
export {};
@@ -1,6 +1,5 @@
var Enum;
(function (Enum) {
var Enum = /*#__PURE__*/function (Enum) {
Enum[Enum["A"] = 0] = "A";
})(Enum || (Enum = {}));
}(Enum || {});
;
export {};
@@ -1,6 +1,5 @@
import { A } from 'lib';
var Enum;
(function (Enum) {
var Enum = /*#__PURE__*/function (Enum) {
Enum[Enum["id"] = A] = "id";
})(Enum || (Enum = {}));
}(Enum || {});
;
@@ -1,7 +1,6 @@
var A;
(function (A) {
var A = /*#__PURE__*/function (A) {
A[A["C"] = 2] = "C";
})(A || (A = {}));
}(A || {});
(function (_A) {
const B = _A.B = 1;
})(A || (A = {}));
@@ -1,5 +1,4 @@
var Example;
(function (Example) {
var Example = /*#__PURE__*/function (Example) {
Example[Example["Value"] = 0] = "Value";
})(Example || (Example = {}));
}(Example || {});
foo;
@@ -1,5 +1,4 @@
var Example;
(function (Example) {
var Example = /*#__PURE__*/function (Example) {
Example[Example["Value"] = 0] = "Value";
})(Example || (Example = {}));
}(Example || {});
foo;

0 comments on commit 93b8a00

Please sign in to comment.