From bdda61a2064b5813b1f722e723d8411343b13dc4 Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Mon, 30 Jan 2023 16:37:21 +0800 Subject: [PATCH 1/5] improve --- .../src/enum.ts | 87 ++++++++++++++----- .../enum/outer-const-foldable/input.ts | 13 +++ .../enum/outer-const-foldable/output.js | 15 ++++ .../src/ast-types/generated/index.ts | 2 - 4 files changed, 91 insertions(+), 26 deletions(-) create mode 100644 packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/input.ts create mode 100644 packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/output.js diff --git a/packages/babel-plugin-transform-typescript/src/enum.ts b/packages/babel-plugin-transform-typescript/src/enum.ts index 95f0481193b4..7b15b921e96f 100644 --- a/packages/babel-plugin-transform-typescript/src/enum.ts +++ b/packages/babel-plugin-transform-typescript/src/enum.ts @@ -143,10 +143,11 @@ export function translateEnumValues( return 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"); const initializer = member.initializer; let value: t.Expression; if (initializer) { - constValue = computeConstantValue(initializer, seen); + constValue = computeConstantValue(initializerPath, seen); if (constValue !== undefined) { seen.set(name, constValue); if (typeof constValue === "number") { @@ -156,8 +157,6 @@ export function translateEnumValues( value = t.stringLiteral(constValue); } } else { - const initializerPath = memberPath.get("initializer"); - if (initializerPath.isReferencedIdentifier()) { ReferencedIdentifier(initializerPath, { t, @@ -195,45 +194,83 @@ export function translateEnumValues( // Based on the TypeScript repository's `computeConstantValue` in `checker.ts`. function computeConstantValue( - expr: t.Node, + path: NodePath, seen: PreviousEnumMembers, -): number | string | typeof undefined { - return evaluate(expr); +): number | string | undefined { + return computeConstantValue(path); - function evaluate(expr: t.Node): number | typeof undefined { + function computeConstantValue(path: NodePath): number | string | undefined { + const expr = path.node; switch (expr.type) { case "StringLiteral": return expr.value; case "UnaryExpression": - return evalUnaryExpression(expr); + return evalUnaryExpression(path as NodePath); case "BinaryExpression": - return evalBinaryExpression(expr); + return evalBinaryExpression(path as NodePath); case "NumericLiteral": return expr.value; case "ParenthesizedExpression": - return evaluate(expr.expression); - case "Identifier": - return seen.get(expr.name); - case "TemplateLiteral": + return computeConstantValue(path.get("expression")); + case "Identifier": { + let value = seen.get(expr.name); + if (value === undefined) { + value = evalIdentifier(path); + if (value !== undefined) { + seen.set(expr.name, value); + } + } + return value; + } + case "TemplateLiteral": { if (expr.quasis.length === 1) { return expr.quasis[0].value.cooked; } - /* falls through */ + + const paths = (path as NodePath).get("expressions"); + const quasis = expr.quasis; + let str = ""; + + for (let i = 0; i < quasis.length; i++) { + str += quasis[i].value.cooked; + + if (i + 1 < quasis.length) { + const value = evalIdentifier(paths[i]); + if (value === undefined) return undefined; + str += value; + } + } + return str; + } default: return undefined; } } - function evalUnaryExpression({ - argument, - operator, - }: t.UnaryExpression): number | typeof undefined { - const value = evaluate(argument); + function evalIdentifier(path: NodePath) { + if (path.isIdentifier()) { + const binding = path.scope.getBinding(path.node.name); + if (binding?.kind === "const") { + const result = path.evaluate(); + if ( + result.confident && + (typeof result.value === "number" || typeof result.value === "string") + ) { + return result.value; + } + } + } + } + + function evalUnaryExpression( + path: NodePath, + ): number | string | undefined { + const value = computeConstantValue(path.get("argument")); if (value === undefined) { return undefined; } - switch (operator) { + switch (path.node.operator) { case "+": return value; case "-": @@ -245,17 +282,19 @@ function computeConstantValue( } } - function evalBinaryExpression(expr: t.BinaryExpression): number | undefined { - const left = evaluate(expr.left); + function evalBinaryExpression( + path: NodePath, + ): number | string | undefined { + const left = computeConstantValue(path.get("left")) as any; if (left === undefined) { return undefined; } - const right = evaluate(expr.right); + const right = computeConstantValue(path.get("right")) as any; if (right === undefined) { return undefined; } - switch (expr.operator) { + switch (path.node.operator) { case "|": return left | right; case "&": diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/input.ts new file mode 100644 index 000000000000..a85e4092eaee --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/input.ts @@ -0,0 +1,13 @@ +// ts 5.0 feature + +const BaseValue = 10; +const Prefix = "/data"; +const enum Values { + First = BaseValue, // 10 + Second, // 11 + Third, // 12 +} +const enum Routes { + Parts = `${Prefix}/parts`, // "/data/parts" + Invoices = `${Prefix}/invoices`, // "/data/invoices" +} diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/output.js b/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/output.js new file mode 100644 index 000000000000..33227ac5fe26 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/output.js @@ -0,0 +1,15 @@ +// ts 5.0 feature + +const BaseValue = 10; +const Prefix = "/data"; +var Values; // 12 +(function (Values) { + Values[Values["First"] = 10] = "First"; + Values[Values["Second"] = 11] = "Second"; + Values[Values["Third"] = 12] = "Third"; +})(Values || (Values = {})); +var Routes; // "/data/invoices" +(function (Routes) { + Routes["Parts"] = "/data/parts"; + Routes["Invoices"] = "/data/invoices"; +})(Routes || (Routes = {})); diff --git a/packages/babel-types/src/ast-types/generated/index.ts b/packages/babel-types/src/ast-types/generated/index.ts index 7d55b779738e..0a11b827f47a 100644 --- a/packages/babel-types/src/ast-types/generated/index.ts +++ b/packages/babel-types/src/ast-types/generated/index.ts @@ -725,7 +725,6 @@ export interface AssignmentPattern extends BaseNode { | TSNonNullExpression; right: Expression; decorators?: Array | null; - optional?: boolean | null; typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null; } @@ -912,7 +911,6 @@ export interface ObjectPattern extends BaseNode { type: "ObjectPattern"; properties: Array; decorators?: Array | null; - optional?: boolean | null; typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null; } From 80f46f8e906315ba7b227ce13d0e252751a89ba2 Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Mon, 30 Jan 2023 20:22:04 +0800 Subject: [PATCH 2/5] improve --- .../src/const-enum.ts | 2 +- .../src/enum.ts | 135 +++++++++++------- .../fixtures/enum/mix-references/output.js | 4 +- .../fixtures/enum/outer-references/output.js | 10 +- 4 files changed, 89 insertions(+), 62 deletions(-) diff --git a/packages/babel-plugin-transform-typescript/src/const-enum.ts b/packages/babel-plugin-transform-typescript/src/const-enum.ts index dd4ff335b036..9e388d37a642 100644 --- a/packages/babel-plugin-transform-typescript/src/const-enum.ts +++ b/packages/babel-plugin-transform-typescript/src/const-enum.ts @@ -27,7 +27,7 @@ export default function transpileConstEnum( ); } - const entries = translateEnumValues(path, t); + const { nodes: entries } = translateEnumValues(path, t); if (isExported) { const obj = t.objectExpression( diff --git a/packages/babel-plugin-transform-typescript/src/enum.ts b/packages/babel-plugin-transform-typescript/src/enum.ts index 7b15b921e96f..44354bcfd0aa 100644 --- a/packages/babel-plugin-transform-typescript/src/enum.ts +++ b/packages/babel-plugin-transform-typescript/src/enum.ts @@ -1,10 +1,13 @@ import { template } from "@babel/core"; import type { NodePath } from "@babel/traverse"; import type * as t from "@babel/types"; +import { isIdentifier, isStringLiteral } from "@babel/types"; import assert from "assert"; type t = typeof t; +const ENUMS = new WeakMap(); + export default function transpileEnum( path: NodePath, t: t, @@ -17,7 +20,7 @@ export default function transpileEnum( } const name = node.id.name; - const fill = enumFill(path, t, node.id); + const { wrapper: fill, data } = enumFill(path, t, node.id); switch (path.parent.type) { case "BlockStatement": @@ -33,6 +36,7 @@ export default function transpileEnum( path.scope.registerDeclaration( path.replaceWith(makeVar(node.id, t, isGlobal ? "var" : "let"))[0], ); + ENUMS.set(path.scope.getBindingIdentifier(name), data); } break; } @@ -81,7 +85,7 @@ const buildEnumMember = (isString: boolean, options: Record) => * `(function (E) { ... assignments ... })(E || (E = {}));` */ function enumFill(path: NodePath, t: t, id: t.Identifier) { - const x = translateEnumValues(path, t); + const { nodes: x, data } = translateEnumValues(path, t); const assignments = x.map(([memberName, memberValue]) => buildEnumMember(t.isStringLiteral(memberValue), { ENUM: t.cloneNode(id), @@ -90,10 +94,13 @@ function enumFill(path: NodePath, t: t, id: t.Identifier) { }), ); - return buildEnumWrapper({ - ID: t.cloneNode(id), - ASSIGNMENTS: assignments, - }); + return { + wrapper: buildEnumWrapper({ + ID: t.cloneNode(id), + ASSIGNMENTS: assignments, + }), + data: data, + }; } /** @@ -131,65 +138,69 @@ const enumSelfReferenceVisitor = { ReferencedIdentifier, }; -export function translateEnumValues( - path: NodePath, - t: t, -): Array<[name: string, value: t.Expression]> { +export function translateEnumValues(path: NodePath, t: t) { const seen: PreviousEnumMembers = new Map(); // Start at -1 so the first enum member is its increment, 0. let constValue: number | string | undefined = -1; let lastName: string; - return 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"); - const initializer = member.initializer; - let value: t.Expression; - if (initializer) { - constValue = computeConstantValue(initializerPath, seen); - if (constValue !== undefined) { - seen.set(name, constValue); - if (typeof constValue === "number") { - value = t.numericLiteral(constValue); + return { + data: seen, + nodes: 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"); + const initializer = member.initializer; + let value: t.Expression; + if (initializer) { + constValue = computeConstantValue(initializerPath, seen); + if (constValue !== undefined) { + seen.set(name, constValue); + if (typeof constValue === "number") { + value = t.numericLiteral(constValue); + } else { + assert(typeof constValue === "string"); + value = t.stringLiteral(constValue); + } } else { - assert(typeof constValue === "string"); - value = t.stringLiteral(constValue); + if (initializerPath.isReferencedIdentifier()) { + ReferencedIdentifier(initializerPath, { + t, + seen, + path, + }); + } else { + initializerPath.traverse(enumSelfReferenceVisitor, { + t, + seen, + path, + }); + } + + value = initializerPath.node; + seen.set(name, undefined); } + } 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 { - if (initializerPath.isReferencedIdentifier()) { - ReferencedIdentifier(initializerPath, { - t, - seen, - path, - }); - } else { - initializerPath.traverse(enumSelfReferenceVisitor, { t, seen, path }); - } - - value = initializerPath.node; + // 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); seen.set(name, undefined); } - } 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); - seen.set(name, undefined); - } - lastName = name; - return [name, value]; - }); + lastName = name; + return [name, value]; + }) as Array<[name: string, value: t.Expression]>, + }; } // Based on the TypeScript repository's `computeConstantValue` in `checker.ts`. @@ -202,6 +213,22 @@ function computeConstantValue( function computeConstantValue(path: NodePath): number | string | undefined { const expr = path.node; switch (expr.type) { + case "MemberExpression": { + const obj = expr.object; + const prop = expr.property; + if ( + !isIdentifier(obj) || + (expr.computed ? !isStringLiteral(prop) : !isIdentifier(prop)) + ) { + return; + } + const bindingIdentifier = path.scope.getBindingIdentifier(obj.name); + const data = ENUMS.get(bindingIdentifier); + if (!data) return; + // @ts-expect-error checked above + return data.get(prop.computed ? prop.value : prop.name); + } + case "StringLiteral": return expr.value; case "UnaryExpression": diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/enum/mix-references/output.js b/packages/babel-plugin-transform-typescript/test/fixtures/enum/mix-references/output.js index 1f38322e0d4c..a7782acec602 100644 --- a/packages/babel-plugin-transform-typescript/test/fixtures/enum/mix-references/output.js +++ b/packages/babel-plugin-transform-typescript/test/fixtures/enum/mix-references/output.js @@ -7,8 +7,8 @@ var Foo; })(Foo || (Foo = {})); var Bar; (function (Bar) { - Bar[Bar["D"] = Foo.a] = "D"; - Bar[Bar["E"] = Bar.D] = "E"; + Bar[Bar["D"] = 10] = "D"; + Bar[Bar["E"] = 10] = "E"; Bar[Bar["F"] = Math.E] = "F"; Bar[Bar["G"] = Bar.E + Foo.c] = "G"; })(Bar || (Bar = {})); diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-references/output.js b/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-references/output.js index e05f31e556a9..f12f2500f92d 100644 --- a/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-references/output.js +++ b/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-references/output.js @@ -6,9 +6,9 @@ var socketType; })(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["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 = {})); From 57e0cffda3ef29e61c776756cb6a39216b9abfcf Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Mon, 30 Jan 2023 20:29:00 +0800 Subject: [PATCH 3/5] fix imports --- packages/babel-plugin-transform-typescript/src/enum.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/babel-plugin-transform-typescript/src/enum.ts b/packages/babel-plugin-transform-typescript/src/enum.ts index 44354bcfd0aa..2cc3e7e330e4 100644 --- a/packages/babel-plugin-transform-typescript/src/enum.ts +++ b/packages/babel-plugin-transform-typescript/src/enum.ts @@ -1,7 +1,6 @@ -import { template } from "@babel/core"; +import { template, types } from "@babel/core"; import type { NodePath } from "@babel/traverse"; import type * as t from "@babel/types"; -import { isIdentifier, isStringLiteral } from "@babel/types"; import assert from "assert"; type t = typeof t; @@ -217,8 +216,10 @@ function computeConstantValue( const obj = expr.object; const prop = expr.property; if ( - !isIdentifier(obj) || - (expr.computed ? !isStringLiteral(prop) : !isIdentifier(prop)) + !types.isIdentifier(obj) || + (expr.computed + ? !types.isStringLiteral(prop) + : !types.isIdentifier(prop)) ) { return; } From 258e539d69078eef9a15c07523256747806b4a6b Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Sat, 18 Feb 2023 22:18:58 +0800 Subject: [PATCH 4/5] review and improve --- .../src/const-enum.ts | 2 +- .../src/enum.ts | 105 +++++++++--------- .../fixtures/enum/mix-references/output.js | 4 +- .../input.ts | 6 + .../output.js | 6 +- 5 files changed, 68 insertions(+), 55 deletions(-) rename packages/babel-plugin-transform-typescript/test/fixtures/enum/{outer-const-foldable => ts5.0-const-foldable}/input.ts (73%) rename packages/babel-plugin-transform-typescript/test/fixtures/enum/{outer-const-foldable => ts5.0-const-foldable}/output.js (77%) diff --git a/packages/babel-plugin-transform-typescript/src/const-enum.ts b/packages/babel-plugin-transform-typescript/src/const-enum.ts index 9e388d37a642..dbb04beb0aba 100644 --- a/packages/babel-plugin-transform-typescript/src/const-enum.ts +++ b/packages/babel-plugin-transform-typescript/src/const-enum.ts @@ -27,7 +27,7 @@ export default function transpileConstEnum( ); } - const { nodes: entries } = translateEnumValues(path, t); + const { enumValues: entries } = translateEnumValues(path, t); if (isExported) { const obj = t.objectExpression( diff --git a/packages/babel-plugin-transform-typescript/src/enum.ts b/packages/babel-plugin-transform-typescript/src/enum.ts index 2cc3e7e330e4..8cb9351df3f9 100644 --- a/packages/babel-plugin-transform-typescript/src/enum.ts +++ b/packages/babel-plugin-transform-typescript/src/enum.ts @@ -1,6 +1,5 @@ -import { template, types } from "@babel/core"; +import { template, types as t } from "@babel/core"; import type { NodePath } from "@babel/traverse"; -import type * as t from "@babel/types"; import assert from "assert"; type t = typeof t; @@ -84,7 +83,7 @@ const buildEnumMember = (isString: boolean, options: Record) => * `(function (E) { ... assignments ... })(E || (E = {}));` */ function enumFill(path: NodePath, t: t, id: t.Identifier) { - const { nodes: x, data } = translateEnumValues(path, t); + const { enumValues: x, data } = translateEnumValues(path, t); const assignments = x.map(([memberName, memberValue]) => buildEnumMember(t.isStringLiteral(memberValue), { ENUM: t.cloneNode(id), @@ -145,7 +144,7 @@ export function translateEnumValues(path: NodePath, t: t) { return { data: seen, - nodes: path.get("members").map(memberPath => { + enumValues: 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"); @@ -205,31 +204,16 @@ export function translateEnumValues(path: NodePath, t: t) { // Based on the TypeScript repository's `computeConstantValue` in `checker.ts`. function computeConstantValue( path: NodePath, - seen: PreviousEnumMembers, + prevMembers?: PreviousEnumMembers, + seen: Set = new Set(), ): number | string | undefined { - return computeConstantValue(path); + return evaluate(path); - function computeConstantValue(path: NodePath): number | string | undefined { + function evaluate(path: NodePath): number | string | undefined { const expr = path.node; switch (expr.type) { - case "MemberExpression": { - const obj = expr.object; - const prop = expr.property; - if ( - !types.isIdentifier(obj) || - (expr.computed - ? !types.isStringLiteral(prop) - : !types.isIdentifier(prop)) - ) { - return; - } - const bindingIdentifier = path.scope.getBindingIdentifier(obj.name); - const data = ENUMS.get(bindingIdentifier); - if (!data) return; - // @ts-expect-error checked above - return data.get(prop.computed ? prop.value : prop.name); - } - + case "MemberExpression": + return evaluateRef(path, prevMembers, seen); case "StringLiteral": return expr.value; case "UnaryExpression": @@ -239,17 +223,9 @@ function computeConstantValue( case "NumericLiteral": return expr.value; case "ParenthesizedExpression": - return computeConstantValue(path.get("expression")); - case "Identifier": { - let value = seen.get(expr.name); - if (value === undefined) { - value = evalIdentifier(path); - if (value !== undefined) { - seen.set(expr.name, value); - } - } - return value; - } + return evaluate(path.get("expression")); + case "Identifier": + return evaluateRef(path, prevMembers, seen); case "TemplateLiteral": { if (expr.quasis.length === 1) { return expr.quasis[0].value.cooked; @@ -263,7 +239,7 @@ function computeConstantValue( str += quasis[i].value.cooked; if (i + 1 < quasis.length) { - const value = evalIdentifier(paths[i]); + const value = evaluateRef(paths[i], prevMembers, seen); if (value === undefined) return undefined; str += value; } @@ -275,17 +251,44 @@ function computeConstantValue( } } - function evalIdentifier(path: NodePath) { - if (path.isIdentifier()) { - const binding = path.scope.getBinding(path.node.name); - if (binding?.kind === "const") { - const result = path.evaluate(); - if ( - result.confident && - (typeof result.value === "number" || typeof result.value === "string") - ) { - return result.value; - } + function evaluateRef( + path: NodePath, + prevMembers: PreviousEnumMembers, + seen: Set, + ): number | string | undefined { + if (path.isMemberExpression()) { + const expr = path.node; + + const obj = expr.object; + const prop = expr.property; + if ( + !t.isIdentifier(obj) || + (expr.computed ? !t.isStringLiteral(prop) : !t.isIdentifier(prop)) + ) { + return; + } + const bindingIdentifier = path.scope.getBindingIdentifier(obj.name); + const data = ENUMS.get(bindingIdentifier); + if (!data) return; + // @ts-expect-error checked above + return data.get(prop.computed ? prop.value : prop.name); + } else if (path.isIdentifier()) { + const name = path.node.name; + + let value = prevMembers?.get(name); + if (value !== undefined) { + return value; + } + + if (seen.has(path.node)) return; + + const bindingInitPath = path.resolve(); // It only resolves constant bindings + if (bindingInitPath) { + seen.add(path.node); + + value = computeConstantValue(bindingInitPath, undefined, seen); + prevMembers?.set(name, value); + return value; } } } @@ -293,7 +296,7 @@ function computeConstantValue( function evalUnaryExpression( path: NodePath, ): number | string | undefined { - const value = computeConstantValue(path.get("argument")); + const value = evaluate(path.get("argument")); if (value === undefined) { return undefined; } @@ -313,11 +316,11 @@ function computeConstantValue( function evalBinaryExpression( path: NodePath, ): number | string | undefined { - const left = computeConstantValue(path.get("left")) as any; + const left = evaluate(path.get("left")) as any; if (left === undefined) { return undefined; } - const right = computeConstantValue(path.get("right")) as any; + const right = evaluate(path.get("right")) as any; if (right === undefined) { return undefined; } diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/enum/mix-references/output.js b/packages/babel-plugin-transform-typescript/test/fixtures/enum/mix-references/output.js index a7782acec602..7ac74a98f5d4 100644 --- a/packages/babel-plugin-transform-typescript/test/fixtures/enum/mix-references/output.js +++ b/packages/babel-plugin-transform-typescript/test/fixtures/enum/mix-references/output.js @@ -3,14 +3,14 @@ var Foo; (function (Foo) { Foo[Foo["a"] = 10] = "a"; Foo[Foo["b"] = 10] = "b"; - Foo[Foo["c"] = Foo.b + x] = "c"; + Foo[Foo["c"] = 20] = "c"; })(Foo || (Foo = {})); var Bar; (function (Bar) { Bar[Bar["D"] = 10] = "D"; Bar[Bar["E"] = 10] = "E"; Bar[Bar["F"] = Math.E] = "F"; - Bar[Bar["G"] = Bar.E + Foo.c] = "G"; + Bar[Bar["G"] = 30] = "G"; })(Bar || (Bar = {})); var Baz; (function (Baz) { diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/enum/ts5.0-const-foldable/input.ts similarity index 73% rename from packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/input.ts rename to packages/babel-plugin-transform-typescript/test/fixtures/enum/ts5.0-const-foldable/input.ts index a85e4092eaee..0acbbb970b5d 100644 --- a/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/input.ts +++ b/packages/babel-plugin-transform-typescript/test/fixtures/enum/ts5.0-const-foldable/input.ts @@ -7,7 +7,13 @@ const enum Values { Second, // 11 Third, // 12 } + +const xxx = 100 + Values.First; +const yyy = xxx; + const enum Routes { Parts = `${Prefix}/parts`, // "/data/parts" Invoices = `${Prefix}/invoices`, // "/data/invoices" + x = `${Values.First}/x`, + y = `${yyy}/y`, } diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/output.js b/packages/babel-plugin-transform-typescript/test/fixtures/enum/ts5.0-const-foldable/output.js similarity index 77% rename from packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/output.js rename to packages/babel-plugin-transform-typescript/test/fixtures/enum/ts5.0-const-foldable/output.js index 33227ac5fe26..e839254369de 100644 --- a/packages/babel-plugin-transform-typescript/test/fixtures/enum/outer-const-foldable/output.js +++ b/packages/babel-plugin-transform-typescript/test/fixtures/enum/ts5.0-const-foldable/output.js @@ -8,8 +8,12 @@ var Values; // 12 Values[Values["Second"] = 11] = "Second"; Values[Values["Third"] = 12] = "Third"; })(Values || (Values = {})); -var Routes; // "/data/invoices" +const xxx = 100 + Values.First; +const yyy = xxx; +var Routes; (function (Routes) { Routes["Parts"] = "/data/parts"; Routes["Invoices"] = "/data/invoices"; + Routes["x"] = "10/x"; + Routes["y"] = "110/y"; })(Routes || (Routes = {})); From b13f9da3e8f84b2507d96d26b3ce2c1f3a0f698b Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Sat, 18 Feb 2023 22:20:08 +0800 Subject: [PATCH 5/5] rebase --- packages/babel-types/src/ast-types/generated/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/babel-types/src/ast-types/generated/index.ts b/packages/babel-types/src/ast-types/generated/index.ts index 0a11b827f47a..7d55b779738e 100644 --- a/packages/babel-types/src/ast-types/generated/index.ts +++ b/packages/babel-types/src/ast-types/generated/index.ts @@ -725,6 +725,7 @@ export interface AssignmentPattern extends BaseNode { | TSNonNullExpression; right: Expression; decorators?: Array | null; + optional?: boolean | null; typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null; } @@ -911,6 +912,7 @@ export interface ObjectPattern extends BaseNode { type: "ObjectPattern"; properties: Array; decorators?: Array | null; + optional?: boolean | null; typeAnnotation?: TypeAnnotation | TSTypeAnnotation | Noop | null; }