fix: allow enum member without initializer after non-literal member (#13865)
This commit is contained in:
parent
c75fa21cb8
commit
cfe6739dc0
@ -98,47 +98,51 @@ function enumFill(path, t, id) {
|
||||
* Z = X | Y,
|
||||
* }
|
||||
*/
|
||||
type PreviousEnumMembers = {
|
||||
[name: string]: number | string;
|
||||
};
|
||||
type PreviousEnumMembers = Map<string, number | string>;
|
||||
|
||||
export function translateEnumValues(
|
||||
path: NodePath<t.TSEnumDeclaration>,
|
||||
t: typeof import("@babel/types"),
|
||||
): Array<[name: string, value: t.Expression]> {
|
||||
const seen: PreviousEnumMembers = Object.create(null);
|
||||
const seen: PreviousEnumMembers = new Map();
|
||||
// Start at -1 so the first enum member is its increment, 0.
|
||||
let prev: number | typeof undefined = -1;
|
||||
let constValue: number | string | undefined = -1;
|
||||
let lastName: string;
|
||||
|
||||
return path.node.members.map(member => {
|
||||
const name = t.isIdentifier(member.id) ? member.id.name : member.id.value;
|
||||
const initializer = member.initializer;
|
||||
let value: t.Expression;
|
||||
if (initializer) {
|
||||
const constValue = evaluate(initializer, seen);
|
||||
constValue = evaluate(initializer, seen);
|
||||
if (constValue !== undefined) {
|
||||
seen[name] = constValue;
|
||||
seen.set(name, constValue);
|
||||
if (typeof constValue === "number") {
|
||||
value = t.numericLiteral(constValue);
|
||||
prev = constValue;
|
||||
} else {
|
||||
assert(typeof constValue === "string");
|
||||
value = t.stringLiteral(constValue);
|
||||
prev = undefined;
|
||||
}
|
||||
} else {
|
||||
value = initializer;
|
||||
prev = undefined;
|
||||
}
|
||||
} else {
|
||||
if (prev !== undefined) {
|
||||
prev++;
|
||||
value = t.numericLiteral(prev);
|
||||
seen[name] = prev;
|
||||
} else {
|
||||
} else if (typeof constValue === "number") {
|
||||
constValue += 1;
|
||||
value = t.numericLiteral(constValue);
|
||||
seen.set(name, constValue);
|
||||
} else if (typeof constValue === "string") {
|
||||
throw path.buildCodeFrameError("Enum member must have initializer.");
|
||||
}
|
||||
} else {
|
||||
// create dynamic initializer: 1 + ENUM["PREVIOUS"]
|
||||
const lastRef = t.memberExpression(
|
||||
t.cloneNode(path.node.id),
|
||||
t.stringLiteral(lastName),
|
||||
true,
|
||||
);
|
||||
value = t.binaryExpression("+", t.numericLiteral(1), lastRef);
|
||||
}
|
||||
|
||||
lastName = name;
|
||||
return [name, value];
|
||||
});
|
||||
}
|
||||
@ -163,7 +167,7 @@ function evaluate(
|
||||
case "ParenthesizedExpression":
|
||||
return evalConstant(expr.expression);
|
||||
case "Identifier":
|
||||
return seen[expr.name];
|
||||
return seen.get(expr.name);
|
||||
case "TemplateLiteral":
|
||||
if (expr.quasis.length === 1) {
|
||||
return expr.quasis[0].value.cooked;
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"throws": "Enum member must have initializer."
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
var E;
|
||||
|
||||
(function (E) {
|
||||
E[E["a"] = Math.sin(1)] = "a";
|
||||
E[E["b"] = 1 + E["a"]] = "b";
|
||||
})(E || (E = {}));
|
||||
13
packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-references/input.ts
vendored
Normal file
13
packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-references/input.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
enum socketType {
|
||||
SOCKET,
|
||||
SERVER,
|
||||
IPC,
|
||||
}
|
||||
|
||||
enum constants {
|
||||
SOCKET = socketType.SOCKET,
|
||||
SERVER = socketType.SERVER,
|
||||
IPC = socketType.IPC,
|
||||
UV_READABLE,
|
||||
UV_WRITABLE,
|
||||
}
|
||||
17
packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-references/output.js
vendored
Normal file
17
packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-references/output.js
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
var socketType;
|
||||
|
||||
(function (socketType) {
|
||||
socketType[socketType["SOCKET"] = 0] = "SOCKET";
|
||||
socketType[socketType["SERVER"] = 1] = "SERVER";
|
||||
socketType[socketType["IPC"] = 2] = "IPC";
|
||||
})(socketType || (socketType = {}));
|
||||
|
||||
var constants;
|
||||
|
||||
(function (constants) {
|
||||
constants[constants["SOCKET"] = socketType.SOCKET] = "SOCKET";
|
||||
constants[constants["SERVER"] = socketType.SERVER] = "SERVER";
|
||||
constants[constants["IPC"] = socketType.IPC] = "IPC";
|
||||
constants[constants["UV_READABLE"] = 1 + constants["IPC"]] = "UV_READABLE";
|
||||
constants[constants["UV_WRITABLE"] = 1 + constants["UV_READABLE"]] = "UV_WRITABLE";
|
||||
})(constants || (constants = {}));
|
||||
Loading…
x
Reference in New Issue
Block a user