diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 2319f7548..cd88c9553 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -159,6 +159,8 @@ export class LuaTransformer { return this.transformExportDeclaration(node as ts.ExportDeclaration); case ts.SyntaxKind.ImportDeclaration: return this.transformImportDeclaration(node as ts.ImportDeclaration); + case ts.SyntaxKind.ImportEqualsDeclaration: + return this.transformImportEqualsDeclaration(node as ts.ImportEqualsDeclaration); case ts.SyntaxKind.ClassDeclaration: return this.transformClassDeclaration(node as ts.ClassDeclaration); case ts.SyntaxKind.ModuleDeclaration: @@ -458,6 +460,38 @@ export class LuaTransformer { } } + public transformImportEqualsDeclaration(declaration: ts.ImportEqualsDeclaration): StatementVisitResult { + const name = this.transformIdentifier(declaration.name); + const expression = ts.isExternalModuleReference(declaration.moduleReference) + ? this.transformExternalModuleReference(declaration.moduleReference) + : this.transformEntityName(declaration.moduleReference); + + return this.createHoistableVariableDeclarationStatement(name, expression, declaration); + } + + public transformExternalModuleReference( + externalModuleReference: ts.ExternalModuleReference + ): ExpressionVisitResult { + return tstl.createCallExpression( + tstl.createIdentifier("require"), + [this.transformExpression(externalModuleReference.expression)], + externalModuleReference + ); + } + + private transformEntityName(entityName: ts.EntityName): ExpressionVisitResult { + return ts.isQualifiedName(entityName) + ? this.transformQualifiedName(entityName) + : this.transformIdentifierExpression(entityName); + } + + public transformQualifiedName(qualifiedName: ts.QualifiedName): ExpressionVisitResult { + const right = tstl.createStringLiteral(this.getIdentifierText(qualifiedName.right), qualifiedName.right); + const left = this.transformEntityName(qualifiedName.left); + + return tstl.createTableIndexExpression(left, right, qualifiedName); + } + public transformClassDeclaration( statement: ts.ClassLikeDeclaration, nameOverride?: tstl.Identifier @@ -3755,7 +3789,7 @@ export class LuaTransformer { } public transformPropertyAccessExpression(expression: ts.PropertyAccessExpression): ExpressionVisitResult { - const property = expression.name.text; + const property = this.getIdentifierText(expression.name); // Check for primitive types to override const type = this.checker.getTypeAtLocation(expression.expression); diff --git a/test/unit/declarations.spec.ts b/test/unit/declarations.spec.ts index a4181b009..d0245dae0 100644 --- a/test/unit/declarations.spec.ts +++ b/test/unit/declarations.spec.ts @@ -92,3 +92,51 @@ test("Declaration instance function callback", () => { const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); expect(result).toBe(20); }); + +test("ImportEquals declaration", () => { + const header = ` + namespace outerNamespace { + export namespace innerNamespace { + export function func() { return "foo" } + } + }; + + import importedFunc = outerNamespace.innerNamespace.func; + `; + + const execution = `return importedFunc();`; + + const result = util.transpileAndExecute(execution, undefined, undefined, header); + expect(result).toEqual("foo"); +}); + +test("ImportEquals declaration ambient", () => { + const header = ` + declare namespace outerNamespace { + namespace innerNamespace { + function func(): string; + } + }; + + import importedFunc = outerNamespace.innerNamespace.func; + `; + + const luaHeader = `outerNamespace = { + innerNamespace = { + func = function() return "foo" end + } + } + `; + + const execution = `return importedFunc();`; + + const result = util.transpileAndExecute(execution, undefined, luaHeader, header); + expect(result).toEqual("foo"); +}); + +test("ImportEquals declaration require", () => { + const source = `import foo = require("bar");`; + + const result = util.transpileString(source); + expect(result.includes(`local foo = require("bar")`)).toBeTruthy(); +});