From 2528103c52fff6f071e9c429e19b5fd9d4dbcdbe Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 17 Nov 2022 23:10:08 +0100 Subject: [PATCH 1/3] Fix unsafe name default export --- src/transformation/visitors/class/index.ts | 6 ++--- .../__snapshots__/identifiers.spec.ts.snap | 24 +++++++++++++++++++ test/unit/identifiers.spec.ts | 12 ++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 5955d6e1f..39e168d86 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -27,9 +27,9 @@ import { LuaTarget } from "../../../CompilerOptions"; export const transformClassDeclaration: FunctionVisitor = (declaration, context) => { // If declaration is a default export, transform to export variable assignment instead if (hasDefaultExportModifier(declaration)) { - const left = createDefaultExportExpression(declaration); - const right = transformClassAsExpression(declaration, context); - return [lua.createAssignmentStatement(left, right, declaration)]; + // Class declaration including assignment to ____exports.default are in preceding statements + transformClassAsExpression(declaration, context); + return []; } const { statements } = transformClassLikeDeclaration(declaration, context); diff --git a/test/unit/__snapshots__/identifiers.spec.ts.snap b/test/unit/__snapshots__/identifiers.spec.ts.snap index 8af819bc0..1077e443c 100644 --- a/test/unit/__snapshots__/identifiers.spec.ts.snap +++ b/test/unit/__snapshots__/identifiers.spec.ts.snap @@ -248,6 +248,30 @@ exports[`undeclared identifier must be a valid lua identifier (object literal sh exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; +exports[`unicode export class 1`] = ` +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Class = ____lualib.__TS__Class +local ____exports = {} +____exports[\\"你好\\"] = __TS__Class() +local _____4F60_597D = ____exports[\\"你好\\"] +_____4F60_597D.name = \\"你好\\" +function _____4F60_597D.prototype.____constructor(self) +end +return ____exports" +`; + +exports[`unicode export default class 1`] = ` +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Class = ____lualib.__TS__Class +local ____exports = {} +____exports.default = __TS__Class() +local _____4F60_597D = ____exports.default +_____4F60_597D.name = \\"你好\\" +function _____4F60_597D.prototype.____constructor(self) +end +return ____exports" +`; + exports[`unicode identifiers in supporting environments (luajit) destructuring property name ("_̀ः٠‿") 1`] = ` "local ____exports = {} function ____exports.__main(self) diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index b5b627b4d..c690e685d 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -285,6 +285,18 @@ describe("unicode identifiers in supporting environments (luajit)", () => { }); }); +test("unicode export class", () => { + util.testModule` + export class 你好 {} + `.expectLuaToMatchSnapshot(); +}); + +test("unicode export default class", () => { + util.testModule` + export default class 你好 {} + `.expectLuaToMatchSnapshot(); +}); + describe("lua keyword as identifier doesn't interfere with lua's value", () => { test("variable (nil)", () => { util.testFunction` From ace9de53762689a7337e9179d6179632c9b6f937 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 17 Nov 2022 23:14:25 +0100 Subject: [PATCH 2/3] Nicely unpack preceding statements --- src/transformation/visitors/class/index.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 39e168d86..4235c722d 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -23,13 +23,17 @@ import { createMethodDecoratingExpression, transformMethodDeclaration } from "./ import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; import { createClassSetup } from "./setup"; import { LuaTarget } from "../../../CompilerOptions"; +import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; export const transformClassDeclaration: FunctionVisitor = (declaration, context) => { // If declaration is a default export, transform to export variable assignment instead if (hasDefaultExportModifier(declaration)) { // Class declaration including assignment to ____exports.default are in preceding statements - transformClassAsExpression(declaration, context); - return []; + const [precedingStatements] = transformInPrecedingStatementScope(context, () => { + transformClassAsExpression(declaration, context); + return []; + }); + return precedingStatements; } const { statements } = transformClassLikeDeclaration(declaration, context); From b714e2aa9cf5b16b610089b16de3bb01c368441f Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 18 Nov 2022 19:31:18 +0100 Subject: [PATCH 3/3] Make functional tests instead of snapshots --- .../__snapshots__/identifiers.spec.ts.snap | 24 ---------------- test/unit/identifiers.spec.ts | 28 ++++++++++++++++--- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/test/unit/__snapshots__/identifiers.spec.ts.snap b/test/unit/__snapshots__/identifiers.spec.ts.snap index 1077e443c..8af819bc0 100644 --- a/test/unit/__snapshots__/identifiers.spec.ts.snap +++ b/test/unit/__snapshots__/identifiers.spec.ts.snap @@ -248,30 +248,6 @@ exports[`undeclared identifier must be a valid lua identifier (object literal sh exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; -exports[`unicode export class 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") -local __TS__Class = ____lualib.__TS__Class -local ____exports = {} -____exports[\\"你好\\"] = __TS__Class() -local _____4F60_597D = ____exports[\\"你好\\"] -_____4F60_597D.name = \\"你好\\" -function _____4F60_597D.prototype.____constructor(self) -end -return ____exports" -`; - -exports[`unicode export default class 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") -local __TS__Class = ____lualib.__TS__Class -local ____exports = {} -____exports.default = __TS__Class() -local _____4F60_597D = ____exports.default -_____4F60_597D.name = \\"你好\\" -function _____4F60_597D.prototype.____constructor(self) -end -return ____exports" -`; - exports[`unicode identifiers in supporting environments (luajit) destructuring property name ("_̀ः٠‿") 1`] = ` "local ____exports = {} function ____exports.__main(self) diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index c690e685d..e3acf8530 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -287,14 +287,34 @@ describe("unicode identifiers in supporting environments (luajit)", () => { test("unicode export class", () => { util.testModule` - export class 你好 {} - `.expectLuaToMatchSnapshot(); + import { 你好 } from "./utfclass"; + export const result = new 你好().hello(); + ` + .addExtraFile( + "utfclass.ts", + `export class 你好 { + hello() { + return "你好"; + } + }` + ) + .expectToEqual({ result: "你好" }); }); test("unicode export default class", () => { util.testModule` - export default class 你好 {} - `.expectLuaToMatchSnapshot(); + import c from "./utfclass"; + export const result = new c().hello(); + ` + .addExtraFile( + "utfclass.ts", + `export default class 你好 { + hello() { + return "你好"; + } + }` + ) + .expectToEqual({ result: "你好" }); }); describe("lua keyword as identifier doesn't interfere with lua's value", () => {