Skip to content

Commit f9a225e

Browse files
hazzard993Perryvw
authored andcommitted
No path resolution for ambient modules (#455)
* Added special console translations * Added tests * Renamed to ConsoleTests * Imported modules are not resolved * Added module tests * Refactored to isAmbientModuleDeclaration * removed interfering tests * private to public * Fixed broken test * Moved isAmbientModuleDeclaration to tsHelper * Refactored to use resolveModule param * Added noResolution decorator * Used new decorator * Correction * Fixed test * Added param to StringCompilerProgram for multiple files * Updated noResolution tests * Merged extraFiles param with input * AAA consideration and updated transpileString
1 parent badd012 commit f9a225e

File tree

5 files changed

+49
-16
lines changed

5 files changed

+49
-16
lines changed

src/Compiler.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ const defaultCompilerOptions: CompilerOptions = {
8989
};
9090

9191
export function createStringCompilerProgram(
92-
input: string, options: CompilerOptions = defaultCompilerOptions, filePath = "file.ts"): ts.Program {
92+
input: string | { [filename: string]: string },
93+
options: CompilerOptions = defaultCompilerOptions,
94+
filePath = "file.ts"
95+
): ts.Program {
9396
const compilerHost = {
9497
directoryExists: () => true,
9598
fileExists: (fileName): boolean => true,
@@ -100,8 +103,17 @@ export function createStringCompilerProgram(
100103
getNewLine: () => "\n",
101104

102105
getSourceFile: (filename: string) => {
103-
if (filename === filePath) {
104-
return ts.createSourceFile(filename, input, ts.ScriptTarget.Latest, false);
106+
switch (typeof input) {
107+
case "string":
108+
if (filename === filePath) {
109+
return ts.createSourceFile(filename, input, ts.ScriptTarget.Latest, false);
110+
}
111+
break;
112+
case "object":
113+
if (filename in input) {
114+
return ts.createSourceFile(filename, input[filename], ts.ScriptTarget.Latest, false);
115+
}
116+
break;
105117
}
106118
if (filename.indexOf(".d.ts") !== -1) {
107119
if (!libCache[filename]) {
@@ -125,16 +137,17 @@ export function createStringCompilerProgram(
125137
// Don't write output
126138
writeFile: (name, text, writeByteOrderMark) => undefined,
127139
};
128-
return ts.createProgram([filePath], options, compilerHost);
140+
const filePaths = typeof input === "string" ? [filePath] : Object.keys(input);
141+
return ts.createProgram(filePaths, options, compilerHost);
129142
}
130143

131144
export function transpileString(
132-
str: string,
145+
input: string | { [filename: string]: string },
133146
options: CompilerOptions = defaultCompilerOptions,
134147
ignoreDiagnostics = false,
135148
filePath = "file.ts"
136149
): string {
137-
const program = createStringCompilerProgram(str, options, filePath);
150+
const program = createStringCompilerProgram(input, options, filePath);
138151

139152
if (!ignoreDiagnostics) {
140153
const diagnostics = ts.getPreEmitDiagnostics(program);

src/Decorator.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export class Decorator {
1313
return DecoratorKind.CustomConstructor;
1414
case "compilemembersonly":
1515
return DecoratorKind.CompileMembersOnly;
16+
case "noresolution":
17+
return DecoratorKind.NoResolution;
1618
case "pureabstract":
1719
return DecoratorKind.PureAbstract;
1820
case "phantom":
@@ -42,6 +44,7 @@ export enum DecoratorKind {
4244
MetaExtension = "MetaExtension",
4345
CustomConstructor = "CustomConstructor",
4446
CompileMembersOnly = "CompileMembersOnly",
47+
NoResolution = "NoResolution",
4548
PureAbstract = "PureAbstract",
4649
Phantom = "Phantom",
4750
TupleReturn = "TupleReturn",

src/LuaTransformer.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -318,14 +318,17 @@ export class LuaTransformer {
318318
const moduleSpecifier = statement.moduleSpecifier as ts.StringLiteral;
319319
const importPath = moduleSpecifier.text.replace(new RegExp("\"", "g"), "");
320320

321-
const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral);
322-
323321
if (!statement.importClause) {
322+
const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral);
324323
result.push(tstl.createExpressionStatement(requireCall));
325324
return result;
326325
}
327326

328327
const imports = statement.importClause.namedBindings;
328+
const type = this.checker.getTypeAtLocation(imports);
329+
const shouldResolve = !tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.NoResolution);
330+
const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral, shouldResolve);
331+
329332
if (ts.isNamedImports(imports)) {
330333
const filteredElements = imports.elements.filter(e => {
331334
const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(e), this.checker);
@@ -379,11 +382,12 @@ export class LuaTransformer {
379382
}
380383
}
381384

382-
private createModuleRequire(moduleSpecifier: ts.StringLiteral): tstl.CallExpression {
383-
const importPath = moduleSpecifier.text.replace(new RegExp("\"", "g"), "");
384-
const resolvedModuleSpecifier = tstl.createStringLiteral(this.getImportPath(importPath));
385-
386-
return tstl.createCallExpression(tstl.createIdentifier("require"), [resolvedModuleSpecifier]);
385+
private createModuleRequire(moduleSpecifier: ts.StringLiteral, resolveModule = true): tstl.CallExpression {
386+
const modulePathString = resolveModule
387+
? this.getImportPath(moduleSpecifier.text.replace(new RegExp("\"", "g"), ""))
388+
: moduleSpecifier.text;
389+
const modulePath = tstl.createStringLiteral(modulePathString);
390+
return tstl.createCallExpression(tstl.createIdentifier("require"), [modulePath]);
387391
}
388392

389393
public transformClassDeclaration(

test/src/util.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ import * as fs from "fs";
1212
import { LuaTransformer } from "../../src/LuaTransformer";
1313

1414
export function transpileString(
15-
str: string,
15+
str: string | { [filename: string]: string },
1616
options?: CompilerOptions,
1717
ignoreDiagnostics = true,
18-
filePath = "file.ts"): string {
18+
filePath = "file.ts"
19+
): string {
1920
if (options) {
2021
if (options.noHeader === undefined) {
2122
options.noHeader = true;

test/unit/require.spec.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,26 @@ export class RequireTests {
2323
expectedPath: string,
2424
options: CompilerOptions,
2525
throwsError: boolean): void {
26-
const regex = /require\("(.*?)"\)/; // This regex extracts `hello` from require("hello")
2726
if (throwsError) {
2827
Expect(() => util.transpileString(`import * from "${usedPath}";`, options, true, filePath)).toThrow();
2928
} else {
3029
const lua = util.transpileString(`import * from "${usedPath}";`, options, true, filePath);
30+
const regex = /require\("(.*?)"\)/;
3131
const match = regex.exec(lua);
3232
Expect(match[1]).toBe(expectedPath);
3333
}
3434
}
3535

36+
@TestCase("", "src.fake")
37+
@TestCase("/** @noResolution */", "fake")
38+
@Test("noResolution on ambient modules causes no path alterations")
39+
public testRequireModule(comment: string, expectedPath: string): void {
40+
const lua = util.transpileString({
41+
"src/file.ts": `import * as fake from "fake";`,
42+
"module.d.ts": `${comment} declare module "fake" {}`,
43+
}, undefined, true, "src/file.ts");
44+
const regex = /require\("(.*?)"\)/;
45+
Expect(regex.exec(lua)[1]).toBe(expectedPath);
46+
}
47+
3648
}

0 commit comments

Comments
 (0)