Skip to content

Commit cc5c472

Browse files
ark120202Perryvw
authored andcommitted
Improve import = require behavior (#608)
1 parent 3ec89e4 commit cc5c472

File tree

4 files changed

+58
-24
lines changed

4 files changed

+58
-24
lines changed

src/LuaTransformer.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ interface Scope {
4242
export interface EmitResolver {
4343
isValueAliasDeclaration(node: ts.Node): boolean;
4444
isReferencedAliasDeclaration(node: ts.Node, checkChildren?: boolean): boolean;
45+
isTopLevelValueImportEqualsWithEntityName(node: ts.ImportEqualsDeclaration): boolean;
4546
moduleExportsSomeValue(moduleReferenceExpression: ts.Expression): boolean;
4647
}
4748

@@ -462,21 +463,38 @@ export class LuaTransformer {
462463

463464
public transformImportEqualsDeclaration(declaration: ts.ImportEqualsDeclaration): StatementVisitResult {
464465
const name = this.transformIdentifier(declaration.name);
465-
const expression = ts.isExternalModuleReference(declaration.moduleReference)
466-
? this.transformExternalModuleReference(declaration.moduleReference)
467-
: this.transformEntityName(declaration.moduleReference);
466+
let expression: tstl.Expression;
467+
if (ts.isExternalModuleReference(declaration.moduleReference)) {
468+
if (!this.resolver.isReferencedAliasDeclaration(declaration)) {
469+
return undefined;
470+
}
471+
472+
expression = this.transformExternalModuleReference(declaration.moduleReference);
473+
} else {
474+
if (this.currentSourceFile === undefined) {
475+
throw TSTLErrors.MissingSourceFile();
476+
}
477+
478+
const shouldEmit =
479+
this.resolver.isReferencedAliasDeclaration(declaration) ||
480+
(!ts.isExternalModule(this.currentSourceFile) &&
481+
this.resolver.isTopLevelValueImportEqualsWithEntityName(declaration));
482+
483+
if (!shouldEmit) {
484+
return undefined;
485+
}
486+
487+
expression = this.transformEntityName(declaration.moduleReference);
488+
}
468489

469490
return this.createHoistableVariableDeclarationStatement(name, expression, declaration);
470491
}
471492

472493
public transformExternalModuleReference(
473494
externalModuleReference: ts.ExternalModuleReference
474495
): ExpressionVisitResult {
475-
return tstl.createCallExpression(
476-
tstl.createIdentifier("require"),
477-
[this.transformExpression(externalModuleReference.expression)],
478-
externalModuleReference
479-
);
496+
// TODO: Should `externalModuleReference` be original node?
497+
return this.createModuleRequire(externalModuleReference.expression as ts.StringLiteral);
480498
}
481499

482500
private transformEntityName(entityName: ts.EntityName): ExpressionVisitResult {

test/unit/declarations.spec.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ test("ImportEquals declaration", () => {
100100
export function func() { return "foo" }
101101
}
102102
};
103-
103+
104104
import importedFunc = outerNamespace.innerNamespace.func;
105105
`;
106106

@@ -117,12 +117,12 @@ test("ImportEquals declaration ambient", () => {
117117
function func(): string;
118118
}
119119
};
120-
120+
121121
import importedFunc = outerNamespace.innerNamespace.func;
122122
`;
123123

124-
const luaHeader = `outerNamespace = {
125-
innerNamespace = {
124+
const luaHeader = `outerNamespace = {
125+
innerNamespace = {
126126
func = function() return "foo" end
127127
}
128128
}
@@ -133,10 +133,3 @@ test("ImportEquals declaration ambient", () => {
133133
const result = util.transpileAndExecute(execution, undefined, luaHeader, header);
134134
expect(result).toEqual("foo");
135135
});
136-
137-
test("ImportEquals declaration require", () => {
138-
const source = `import foo = require("bar");`;
139-
140-
const result = util.transpileString(source);
141-
expect(result.includes(`local foo = require("bar")`)).toBeTruthy();
142-
});

test/unit/modules.spec.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as ts from "typescript";
12
import * as tstl from "../../src";
23
import { TSTLErrors } from "../../src/TSTLErrors";
34
import * as util from "../util";
@@ -11,7 +12,11 @@ describe("module import/export elision", () => {
1112
`;
1213

1314
const expectToElideImport = (code: string) => {
14-
const lua = util.transpileString({ "module.d.ts": moduleDeclaration, "main.ts": code }, undefined, false);
15+
const lua = util.transpileString(
16+
{ "module.d.ts": moduleDeclaration, "main.ts": code },
17+
{ module: ts.ModuleKind.CommonJS },
18+
false
19+
);
1520

1621
expect(() => util.executeLua(lua)).not.toThrow();
1722
};
@@ -37,6 +42,13 @@ describe("module import/export elision", () => {
3742
`);
3843
});
3944

45+
test("should elide `import =` declarations", () => {
46+
expectToElideImport(`
47+
import module = require("module");
48+
const foo: module.Type = "bar";
49+
`);
50+
});
51+
4052
test("should elide type exports", () => {
4153
const code = `
4254
declare const _G: any;

test/unit/require.spec.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import * as ts from "typescript";
12
import * as util from "../util";
23

4+
const requireRegex = /require\("(.*?)"\)/;
5+
36
test.each([
47
{
58
filePath: "main.ts",
@@ -79,8 +82,7 @@ test.each([
7982
expect(() => util.transpileString(input, options)).toThrow();
8083
} else {
8184
const lua = util.transpileString(input, options);
82-
const regex = /require\("(.*?)"\)/;
83-
const match = regex.exec(lua);
85+
const match = requireRegex.exec(lua);
8486

8587
if (util.expectToBeDefined(match)) {
8688
expect(match[1]).toBe(expectedPath);
@@ -96,11 +98,20 @@ test.each([{ comment: "", expectedPath: "src.fake" }, { comment: "/** @noResolut
9698
"src/main.ts": `import * as fake from "fake"; fake;`,
9799
"module.d.ts": `${comment} declare module "fake" {}`,
98100
});
99-
const regex = /require\("(.*?)"\)/;
100-
const match = regex.exec(lua);
101+
const match = requireRegex.exec(lua);
101102

102103
if (util.expectToBeDefined(match)) {
103104
expect(match[1]).toBe(expectedPath);
104105
}
105106
}
106107
);
108+
109+
test("ImportEquals declaration require", () => {
110+
const input = `import foo = require("./foo/bar"); foo;`;
111+
112+
const lua = util.transpileString(input, { module: ts.ModuleKind.CommonJS });
113+
const match = requireRegex.exec(lua);
114+
if (util.expectToBeDefined(match)) {
115+
expect(match[1]).toBe("foo.bar");
116+
}
117+
});

0 commit comments

Comments
 (0)